Mur*_*a Z 4 python http-headers flask python-3.x
我正在尝试设置Content-Disposition
标头以将文件发送到客户端.文件名是Unicode.当我尝试设置标题时,它失败了UnicodeEncodeError
.我试过的各种组合encode
和decode
,但不能让它开始工作.如何发送带有Unicode文件名的文件?
destination_file = '??????_report.html'
response.headers['Content-Disposition'] = 'attachment; filename=' + destination_file
Run Code Online (Sandbox Code Playgroud)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/server.py", line 495, in send_header
("%s: %s\r\n" % (keyword, value)).encode('latin-1', 'strict'))
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 41-42: ordinal not in range(256)
Run Code Online (Sandbox Code Playgroud)
RFC 2231第4节描述了如何指定要使用的编码而不是Latin-1作为标头值.使用标头选项filename*=UTF-8''...
,其中...
是url编码的名称.您还可以包含filename
提供Latin-1后备的选项.
直到最近,浏览器才一直支持这一点.此页面包含一些有关浏览器支持的指标.值得注意的是,IE8将忽略UTF-8选项,如果UTF-8选项出现在Latin-1选项之前,它将完全失败.
Flask 1.0 支持send_file
使用Unicode文件名进行调用.如果使用Flask 1.0,则可以使用send_file
with as_attachment=True
和Unicode文件名.
from flask import send_file
@app.route('/send-python-report')
def send_python_report():
return send_file('??????_report.html', as_attachment=True)
Run Code Online (Sandbox Code Playgroud)
在此之前,您可以使用Flask将使用的相同过程手动构建标题.
import unicodedata
from flask import send_file
from werkzeug.urls import url_quote
@app.route('/send-python-report')
def send_python_report():
filename = '??????_report.html'
rv = send_file(filename)
try:
filename = filename.encode('latin-1')
except UnicodeEncodeError:
filenames = {
'filename': unicodedata.normalize('NFKD', filename).encode('latin-1', 'ignore'),
'filename*': "UTF-8''{}".format(url_quote(filename)),
}
else:
filenames = {'filename': filename}
rv.headers.set('Content-Disposition', 'attachment', **filenames)
return rv
Run Code Online (Sandbox Code Playgroud)
为了安全起见,send_from_directory
如果文件名由用户输入提供,则应使用.该过程与上述相同,取代了该功能.
WSGI不确保头选项的顺序,因此如果要支持IE8,则必须使用dump_options_header
with 完全手动构造头值OrderedDict
.否则,filename*
可能会出现之前filename
,如上所述,在IE8中不起作用.
from collections import OrderedDict
import unicodedata
from flask import send_file
from werkzeug.http import dump_options_header
from werkzeug.urls import url_quote
@app.route('/send-python-report')
def send_python_report():
filename = '??????_report.html'
rv = send_file(filename)
filenames = OrderedDict()
try:
filename = filename.encode('latin-1')
except UnicodeEncodeError:
filenames['filename'] = unicodedata.normalize('NFKD', filename).encode('latin-1', 'ignore')
filenames['filename*']: "UTF-8''{}".format(url_quote(filename))
else:
filenames['filename'] = filename
rv.headers.set('Content-Disposition', dump_options_header('attachment', filenames))
return rv
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2280 次 |
最近记录: |