最近在使用flask时遇到了一个问题:
@app.route('/getfile/<timestamp>/<filename>') def download(timestamp, filename): dirpath = os.path.join(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'upload'), timestamp) return send_from_directory(dirpath, filename, as_attachment=True)
在本机创建 upload/1512026299/%E6%97%A0%E6%A0%87%E9%A2%98.png
后,运行上方代码。在访问 /getfile/1512026299/%E6%97%A0%E6%A0%87%E9%A2%98.png
时,会抛出下面的异常:
127.0.0.1 - - [30/Nov/2017 21:39:05] "GET /getfile/1512026299/%E6%97%A0%E6%A0%87%E9%A2%98.png HTTP/1.1" 200 -
Error on request:
Traceback (most recent call last):
File "C:\Program Files\Python36\lib\site-packages\werkzeug\serving.py", line 209, in run_wsgi
execute(self.server.app)
File "C:\Program Files\Python36\lib\site-packages\werkzeug\serving.py", line 200, in execute
write(data)
File "C:\Program Files\Python36\lib\site-packages\werkzeug\serving.py", line 168, in write
self.send_header(key, value)
File "C:\Program Files\Python36\lib\http\server.py", line 508, in send_header
("%s: %s\r\n" % (keyword, value)).encode('latin-1', 'strict'))
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 43-45: ordinal not in range(256)
尝试解决无果,于是贴到了 StackOverflow 上寻求解决方案,结果发现这是flask自身的坑……
flask在send_file时(由send_from_directory调用),如果使用as_attachement=True
,就会将文件名放到header里。然后flask还不支持使用unicode方式编码URL,于是就出现了这个问题。
这个问题在GitHub上已经有人修复并请求merge了,应该不久后就能解决。如果真的急用,还是有临时解决方案的,详细的可以点进上方链接(https://stackoverflow.com/questions/47575665/flask-raises-unicodeencodeerror-latin-1-when-send-attachment-with-utf-8-charac/47577423)中查看。