用werkzeug处理unicode文本?
所以我试图让浏览器下载一个具有特定名称的文件,该文件存储在数据库中。 为了防止文件名冲突,文件使用GUID保存在磁盘上,当需要实际下载文件时,数据库的文件名将提供给浏览器。 这个名字是用日语写的,当我在页面上显示它时,它很好,所以它在数据库中保存OK。 当我尝试实际上让浏览器以该名称下载它时:
return send_from_directory(app.config['FILE_FOLDER'], name_on_disk,
as_attachment=True, attachment_filename = filename)
Flask引发错误:
UnicodeEncodeError: 'ascii' codec can't encode characters in position 15-20:
ordinal not in range(128)
这个错误似乎不是来自我的代码,而是来自Werkzeug的一部分:
/werkzeug/http.py", line 150, in quote_header_value
value = str(value)
这是为什么发生? 根据他们的文档,Flask是“100%Unicode”
在我重写我的代码之前,我确实遇到了这个问题,并通过在Werkzeug中修改了很多东西来修复它,但我真的不希望为已部署的应用程序执行此操作,因为这是一种痛苦和不好的做法。
Python 2.7.6 (default, Nov 26 2013, 12:52:49)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
文件名=“[얼티메이트] [131225]电视アニメ「キルクリル」オリジナルサウンドラック(FLAC).zip”
打印repr(文件名)
'[xecx96xbcxedx8bxb0xebxa9x94xecx9dxb4xedx8axb8] [131225] TVxe3x82xa2xe3x83x8bxe3x83xa1xe3x80x8cxe3x82xadxe3x83xabxe3x83xa9xe3x82xadxe3x83xabxe3x80x8dxe3x82xaaxe3x83xaaxe3x82xb8xe3x83x8axe3x83xabxe3x82xb5xe3x82xa6xe3x83xb3xe3x83x89xe3x83x88xe3x83xa9xe3x83x83xe3x82xaf (FLAC).zip'
>>>
在处理非ASCII数据时,应该明确地传递unicode字符串(输入unicode
)。 通常在Flask中,bytestrings被假定为具有ascii
编码。
我有类似的问题。 我原本以此为附件发送文件:
return send_file(dl_fd,
mimetype='application/pdf',
as_attachment=True,
attachment_filename=filename)
其中dl_fd
是我的文件的文件描述符。
unicode文件名不起作用,因为HTTP标头不支持它。 相反,基于来自这个Flask问题的信息和RFC 2231的这些测试用例,我重写了上面的内容来编码文件名:
response = make_response(send_file(dl_fd,
mimetype='application/pdf'
))
response.headers["Content-Disposition"] =
"attachment; "
"filename*=UTF-8''{quoted_filename}".format(
quoted_filename=urllib.quote(filename.encode('utf8'))
)
return response
基于测试用例,上述内容不适用于IE8,但适用于列出的其他浏览器。 (我亲自在Mac上测试了Firefox,Safari和Chrome)
你应该使用像这样的东西:
@route('/attachment/<int:attachment_id>/<filename>', methods=['GET'])
def attachment(attachment_id, filename):
attachment_meta = AttachmentMeta(attachment_id, filename)
if not attachment_meta:
flask.abort(404)
return flask.send_from_directory(
directory=flask.current_app.config['UPLOAD_FOLDER'],
filename=attachment_meta.filepath,
)
这样url_for('attachment',1,u'Москва 北京 תֵּל־אָבִיב.pdf')
将产生:
/attachment/1/%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0%20%E5%8C%97%E4%BA%AC%20%D7%AA%D6%B5%D6%BC%D7%9C%D6%BE%D7%90%D6%B8%D7%91%D6%B4%D7%99%D7%91.pdf
浏览器将以正确的unicode名称显示或保存此文件。 不要使用as_attachment=True
,因为这不起作用。
上一篇: handling unicode text with werkzeug?
下一篇: Can you have more than one Google Site Verification tags