flask send_file和unicode文件名:在IE中失效

2 投票
2 回答
3078 浏览
提问于 2025-04-17 14:25

我写了一个函数,可以动态生成一个csv文件,并让用户下载。

下面是代码:

@app.route('/survey/<survey_id>/report')
def survey_downloadreport(survey_id):  
    survey, bsonobj = survey_get(survey_id)
    resps = response_get_multi(survey_id)

    fields = ["_id", "sid", "date", "user_ip"]
    fields.extend(survey.formfields)    

    csvf = StringIO.StringIO()
    wr = csv.DictWriter(csvf, fields, encoding = 'cp949')
    wr.writerow(dict(zip(fields, fields)))
    for resp in resps :
        wr.writerow(resp)

    csvf.seek(0)

    now = datetime.datetime.now()
    report_name = survey.name + "(" + \
                  now.strftime("%Y-%m-%d-%H:%M:%S") +\
                  ")" + ".csv"

    report_name = report_name.encode("utf-8")



    return send_file(csvf,
                 as_attachment = True,
                 attachment_filename = report_name)

你可以看到,文件名是从unicode转换成字符串的,使用的是utf-8编码(具体来说,是韩文字符)。

问题是,当在IE浏览器中查看页面时,文件名完全显示不正常(在chrome中没有问题)。

看起来需要修改一些头部信息,以便让不同的浏览器能够正确解析,但我不知道在flask中该怎么做。

2 个回答

2

使用 Content-Disposition: attachment; filename="..." 来设置下载文件的名称——这就是 Flask 的 send_file 所做的——对于非 ASCII 字符来说并不可靠。

在 Flask 使用的 werkzeug.http 库和你想要支持的所有浏览器中,直到有对 RFC 5987 的支持,这个问题是无法解决的。

与此同时,一个更可靠的跨浏览器方法是,在你创建链接时,把 UTF-8 编码的文件名放在 URI 的末尾,也就是说:

IRI path: /survey/1/report/안녕.csv
URI path: /survey/1/report/%ec%95%88%eb%85%95.csv

想了解更多背景信息,可以查看 如何为 HTTP 头编码 UTF8 文件名?(Python, Django)

3

试着在 send_file 里加上

mimetype = 'text/csv; charset=x-EBCDIC-KoreanAndKoreanExtended'

这个代码。

撰写回答