RFC 2231第4节中介绍了如何指定一个编码以替代ASCII码用于头部信息。使用头选项filename*=UTF-8''...
,其中...
是url编码的名称。您还可以包括filename
选项,提供一个ASCII码的备选项。
Flask >= 1.0支持使用Unicode文件名调用send_from_directory
和send_file
函数。您可以使用send_from_directory
函数和一个Unicode文件名,并设置参数as_attachment=True
以作为附件下载。
from flask import send_from_directory
@app.route("/send-python-report")
def send_python_report():
return send_from_directory("reports", "python_report.html", as_attachment=True)
为了安全起见,如果文件名由用户输入提供,请确保使用send_from_directory
而不是send_file
。
在 Flask 1.0 之前,您可以手动构建标题,使用Flask 使用的相同过程。
import unicodedata
from urllib.parse import quote
from flask import send_from_directory
@app.route('/send-python-report')
def send_python_report():
filename = "python_report.html"
rv = send_from_directory("reports", filename)
try:
filename.encode("ascii")
except UnicodeEncodeError:
simple = unicodedata.normalize("NFKD", filename)
simple = simple.encode("ascii", "ignore").decode("ascii")
quoted = quote(filename, safe="!#$&+-.^_`|~")
names = {"filename": simple, "filename*": f"UTF-8''{quoted}"}
else:
names = {"filename": filename}
rv.headers.set("Content-Disposition", "attachment", **names)
return rv
直到近年来(2017年之前),浏览器并没有始终支持此功能。这个页面列出了一些浏览器支持的度量数据。值得注意的是,IE8将忽略UTF-8选项,并在ASCII选项之前存在UTF-8选项时完全失败。