加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

Django 实现下载功能时中文文件名问题

发布时间:2020-12-20 10:42:33 所属栏目:Python 来源:网络整理
导读:? 先上最终解决代码(有待验证各浏览器效果): def download_file(request,file_path): file_name = os.path.basename(file_path) if not os.path.isfile(file_path): return HttpResponse(file_name) def file_iterator(tar_file_path,chunk_size=512 ): w

?

先上最终解决代码(有待验证各浏览器效果):

def download_file(request,file_path):
    file_name = os.path.basename(file_path)
    if not os.path.isfile(file_path):
        return HttpResponse(file_name)

    def file_iterator(tar_file_path,chunk_size=512):
        with open(tar_file_path,mode=rb) as file:
            while True:
                content = file.read(chunk_size)
                if content:
                    yield content
                else:
                    break

    try:
        response = StreamingHttpResponse(file_iterator(file_path))
        response[Content-Type] = application/octet-streamresponse["Content-Disposition"] = "attachment; filename*=UTF-8‘‘{}".format(escape_uri_path(file_name)) except:
        return HttpResponse("Sorry but Not Found the File")

    return response

?

重点在于黄色记号笔标注的那行代码。
网上大多资料都是这么写的:

response[Content-Disposition] = attachment;filename="{}".format(file_name)

?

这种写法对应纯英文的文件名是没有问题的,因为 Content-Disposition 里面的 filename ,不是RFC标准,仅支持ASCII编码的文件名。如果文件名不是英文的,就会出现名字乱码,或者被改名的情况。

?

如何直接采用解码的方式也还是会出现byte数组的文件名:

response[Content-Disposition] = attachment;filename="{}".format(file_name.encode(utf8))

得到的结果类似于这样:b‘-xc6-xbd-xcc-xa8-xc4-xda-xb2-xbf-xb2-xe2-xca-xd4.xlsx‘ (3).xls

?

原因是不同浏览器对于下载文件文件名的编码解析格式不一样,常用浏览器解析格式如下:

  • IE浏览器,采用URLEncoder编码
  • Opera浏览器,采用filename*方式
  • Safari浏览器,采用ISO编码的中文输出
  • Chrome浏览器,采用Base64编码或ISO编码的中文输出
  • FireFox浏览器,采用Base64或filename*或ISO编码的中文输出

?

如果硬来的话就是在后台把文件名先 encode 成 bytes,再判断浏览器,根据不同的浏览器用相应的编码decode一下就好了
例如浏览器是FireFox,后台编码是 utf-8,则进行如下操作

response[Content-Disposition] = attachment; filename= + filename.encode(utf-8).decode(ISO-8859-1)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读