Python如何解决secure_filename对中文不支持问题


Posted in Python onJuly 16, 2021

前言:最近使用到了secure_filename,然后悲剧的发现中文居然不展示出来,于是我慢慢的debug,终于找到问题了。

一、最近使用secure_filename发现的问题

文件名是中文版的,悲剧的是中文以及其他特殊字符会被省略。

Python如何解决secure_filename对中文不支持问题

二、后面找到了原因

原来secure_filename()函数只返回ASCII字符,非ASCII字符会被过滤掉。

三、解决方案

找到secure_filename(filename)函数,修改它的源代码。

secure_filename(filename)函数源代码:
def secure_filename(filename: str) -> str:
    r"""Pass it a filename and it will return a secure version of it.  This
    filename can then safely be stored on a regular file system and passed
    to :func:`os.path.join`.  The filename returned is an ASCII only string
    for maximum portability.

    On windows systems the function also makes sure that the file is not
    named after one of the special device files.

    >>> secure_filename("My cool movie.mov")
    'My_cool_movie.mov'
    >>> secure_filename("../../../etc/passwd")
    'etc_passwd'
    >>> secure_filename('i contain cool \xfcml\xe4uts.txt')
    'i_contain_cool_umlauts.txt'

    The function might return an empty filename.  It's your responsibility
    to ensure that the filename is unique and that you abort or
    generate a random filename if the function returned an empty one.

    .. versionadded:: 0.5

    :param filename: the filename to secure
    """
    filename = unicodedata.normalize("NFKD", filename)
    filename = filename.encode("ascii", "ignore").decode("ascii")

    for sep in os.path.sep, os.path.altsep:
        if sep:
            filename = filename.replace(sep, " ")
    filename = str(_filename_ascii_strip_re.sub("", "_".join(filename.split()))).strip(
        "._"
    )

    # on nt a couple of special files are present in each folder.  We
    # have to ensure that the target file is not such a filename.  In
    # this case we prepend an underline
    if (
        os.name == "nt"
        and filename
        and filename.split(".")[0].upper() in _windows_device_files
    ):
        filename = f"_{filename}"

    return filename

secure_filename(filename)函数修改后的代码:

def secure_filename(filename: str) -> str:
    r"""Pass it a filename and it will return a secure version of it.  This
    filename can then safely be stored on a regular file system and passed
    to :func:`os.path.join`.  The filename returned is an ASCII only string
    for maximum portability.

    On windows systems the function also makes sure that the file is not
    named after one of the special device files.

    >>> secure_filename("My cool movie.mov")
    'My_cool_movie.mov'
    >>> secure_filename("../../../etc/passwd")
    'etc_passwd'
    >>> secure_filename('i contain cool \xfcml\xe4uts.txt')
    'i_contain_cool_umlauts.txt'

    The function might return an empty filename.  It's your responsibility
    to ensure that the filename is unique and that you abort or
    generate a random filename if the function returned an empty one.

    .. versionadded:: 0.5

    :param filename: the filename to secure
    """
    filename = unicodedata.normalize("NFKD", filename)
    filename = filename.encode("utf8", "ignore").decode("utf8")   # 编码格式改变

    for sep in os.path.sep, os.path.altsep:
        if sep:
            filename = filename.replace(sep, " ")
    _filename_ascii_add_strip_re = re.compile(r'[^A-Za-z0-9_\u4E00-\u9FBF\u3040-\u30FF\u31F0-\u31FF.-]')
    filename = str(_filename_ascii_add_strip_re.sub('', '_'.join(filename.split()))).strip('._')             # 添加新规则

    # on nt a couple of special files are present in each folder.  We
    # have to ensure that the target file is not such a filename.  In
    # this case we prepend an underline
    if (
        os.name == "nt"
        and filename
        and filename.split(".")[0].upper() in _windows_device_files
    ):
        filename = f"_{filename}"

    return filename

四、效果展示

我们很清楚的看到了效果,目前是支持中文的

Python如何解决secure_filename对中文不支持问题

到此这篇关于Python如何解决secure_filename对中文不支持问题的文章就介绍到这了,更多相关Python secure_filename不支持中文内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python远程桌面协议RDPY安装使用介绍
Apr 15 Python
Python变量作用范围实例分析
Jul 07 Python
详解Django通用视图中的函数包装
Jul 21 Python
Python延时操作实现方法示例
Aug 14 Python
Python学习笔记之pandas索引列、过滤、分组、求和功能示例
Jun 03 Python
Django 请求Request的具体使用方法
Nov 11 Python
TensorFlow Saver:保存和读取模型参数.ckpt实例
Feb 10 Python
python3实现往mysql中插入datetime类型的数据
Mar 02 Python
在django中form的label和verbose name的区别说明
May 20 Python
python使用re模块爬取豆瓣Top250电影
Oct 20 Python
快速解决pymongo操作mongodb的时区问题
Dec 05 Python
python爬取企查查企业信息之selenium自动模拟登录企查查
Apr 08 Python
利用Matlab绘制各类特殊图形的实例代码
Flask response响应的具体使用
Python 快速验证代理IP是否有效的方法实现
Jul 15 #Python
Django路由层如何获取正确的url
Jul 15 #Python
Python实现排序方法常见的四种
Jul 15 #Python
手把手教你使用TensorFlow2实现RNN
一篇文章弄懂Python关键字、标识符和变量
You might like
php打包网站并在线压缩为zip
2016/02/13 PHP
PHP入门教程之自定义函数用法详解(创建,调用,变量,参数,返回值等)
2016/09/11 PHP
PHP反射学习入门示例
2019/06/14 PHP
PHP7 其他修改
2021/03/09 PHP
javascript小数四舍五入多种方法实现
2012/12/23 Javascript
js模拟hashtable的简单实例
2014/03/06 Javascript
高效利用Angular中内置服务$http、$location等
2016/03/22 Javascript
BootStrap智能表单实战系列(四)表单布局介绍
2016/06/13 Javascript
JS实现列表的响应式排版(推荐)
2016/09/01 Javascript
JS简单随机数生成方法
2016/09/05 Javascript
实现easyui的datagrid导出为excel的示例代码
2016/11/10 Javascript
jQuery+HTML5实现弹出创意搜索框层
2016/12/29 Javascript
Node.js中.pfx后缀文件的处理方法
2017/03/10 Javascript
JavaScript原型继承_动力节点Java学院整理
2017/06/30 Javascript
Vue官网todoMVC示例代码
2018/01/29 Javascript
Angular利用内容投射向组件输入ngForOf模板的方法
2018/03/05 Javascript
vue中将html字符串转换成html后遇到的问题小结
2018/12/10 Javascript
JavaScript"模拟事件"的注意要点详解
2019/02/13 Javascript
Vue中通过Vue.extend动态创建实例的方法
2019/08/13 Javascript
[01:00:10]完美世界DOTA2联赛PWL S2 FTD vs Inki 第二场 11.21
2020/11/24 DOTA
wxpython中Textctrl回车事件无效的解决方法
2016/07/21 Python
实例详解Python装饰器与闭包
2019/07/29 Python
浅析pandas 数据结构中的DataFrame
2019/10/12 Python
python 线性回归分析模型检验标准--拟合优度详解
2020/02/24 Python
python程序如何进行保存
2020/07/03 Python
JPA的优势都有哪些
2013/07/04 面试题
公司部门司机岗位职责
2014/01/03 职场文书
运动会入场式解说词
2014/02/18 职场文书
运动会广播稿150字(9篇)
2014/09/20 职场文书
社区党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
2015年安康杯竞赛活动总结
2015/03/26 职场文书
经济纠纷起诉状
2015/05/20 职场文书
2016师德师风学习心得体会
2016/01/12 职场文书
JavaScript 反射学习技巧
2021/10/16 Javascript
Pandas 数据编码的十种方法
2022/04/20 Python
Python保存并浏览用户的历史记录
2022/04/29 Python