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中实现参数类型检查的简单方法
Apr 21 Python
Python中的迭代器与生成器高级用法解析
Jun 28 Python
Sanic框架蓝图用法实例分析
Jul 17 Python
Python统计纯文本文件中英文单词出现个数的方法总结【测试可用】
Jul 25 Python
jenkins配置python脚本定时任务过程图解
Oct 29 Python
python二分法查找算法实现方法【递归与非递归】
Dec 06 Python
Python scrapy增量爬取实例及实现过程解析
Dec 24 Python
详解Python中的分支和循环结构
Feb 11 Python
pycharm-professional-2020.1下载与激活的教程
Sep 21 Python
详解Python中list[::-1]的几种用法
Nov 16 Python
Python中过滤字符串列表的方法
Dec 22 Python
Python机器学习之基础概述
May 19 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 Class 文章
2007/04/04 PHP
php可扩展的验证类实例(可对邮件、手机号、URL等验证)
2015/07/09 PHP
PHP5.5.15+Apache2.4.10+MySQL5.6.20配置方法分享
2016/05/06 PHP
php魔法函数与魔法常量使用介绍
2017/07/23 PHP
laravel实现分页样式替换示例代码(增加首、尾页)
2017/09/22 PHP
jQuery关于导航条背景切换效果实现示例
2013/09/04 Javascript
js捕获鼠标滚轮事件代码
2013/12/16 Javascript
页面图片浮动左右滑动效果的简单实现案例
2014/02/10 Javascript
JQuery性能优化的几点建议
2014/05/14 Javascript
ES6下React组件的写法示例代码
2017/05/04 Javascript
JS实现的将html转为pdf功能【基于浏览器端插件jsPDF】
2018/02/06 Javascript
解决nodejs的npm命令无反应的问题
2018/05/17 NodeJs
React 使用browserHistory项目访问404问题解决
2018/06/01 Javascript
JS加密插件CryptoJS实现的DES加密示例
2018/08/16 Javascript
jQuery实现简易聊天框
2020/02/08 jQuery
vue 实现基础组件的自动化全局注册
2020/12/25 Vue.js
[02:40]DOTA2殁境神蚀者 英雄基础教程
2013/11/26 DOTA
python控制台显示时钟的示例
2014/02/24 Python
Python selenium 三种等待方式详解(必会)
2016/09/15 Python
Request的中断和ErrorHandler实例解析
2018/02/12 Python
Python2和Python3的共存和切换使用
2019/04/12 Python
Python定时任务随机时间执行的实现方法
2019/08/14 Python
浅析Python3 pip换源问题
2020/01/06 Python
Python GUI编程学习笔记之tkinter中messagebox、filedialog控件用法详解
2020/03/30 Python
解决python运行效率不高的问题
2020/07/20 Python
如何将anaconda安装配置的mmdetection环境离线拷贝到另一台电脑
2020/10/15 Python
python批量检查两个对应的txt文件的行数是否一致的实例代码
2020/10/31 Python
荷兰街头时尚之家:Funkie House
2019/03/18 全球购物
全球最大化妆品零售网站:SkinStore
2020/10/24 全球购物
七年级地理教学反思
2014/01/26 职场文书
《藤野先生》教学反思
2014/02/19 职场文书
合作协议书模板
2014/10/10 职场文书
2016年毕业实习心得体会范文
2015/10/09 职场文书
Linux安装Nginx步骤详解
2021/03/31 Servers
MySQL 重命名表的操作方法及注意事项
2021/05/21 MySQL
SpringBoot快速入门详解
2021/07/21 Java/Android