zoukankan      html  css  js  c++  java
  • Django 实现下载功能时中文文件名问题

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

    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-stream'response["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')
  • 相关阅读:
    数组 例题解析
    第六章 数组
    循环控制 例题解析
    第五章 循环控制
    第四章 选择结构程序设计
    第三章 数据的输入与输出
    第一章 程序设计及C语言概述
    C 字符串类型例题讲解与实现字符串库函数
    0XX_javascript核心
    012品优购03
  • 原文地址:https://www.cnblogs.com/zoneofmine/p/11532457.html
Copyright © 2011-2022 走看看