Flask返回中文名文件的文件流对象无响应


Flask返回中文名文件的文件流对象无响应

使用Flask的Response返回文件流对象的时候遇到这样的问题,返回英文名文件时一切正常,当返回中文名称的文件时浏览器正常,网络请求也返回200的响应但却没有下载文件,抓包发现返回的响应头里并没有Content-Type和Content-Disposition字段,分析可能是这个原因。经过搜索发现也有人遇到过这个问题,最终通过urllib模块里方法编码文件名称后能够正常返回。

from urllib.parse import quote

...
file_name = "测试.xlsx"
response.headers['Content-Type'] = 'application/octet-stream'
response.headers['Content-Disposition'] = 'attachment;filename*=utf-8"{0}"'.format(quote(file_name))
return response

当以上代码运行一段时间发现firefox浏览器下载文件会变成utf-8测试.xlsx_这样的文件名称,又经过一番搜索和尝试,最后发现直接将文件名编码为latin-1和iso-8859-1这两个编码能够所有浏览器都能显示正常,如下:

file_name = "测试.xlsx"
response.headers['Content-Type'] = 'application/octet-stream'
response.headers['Content-Disposition'] = 'attachment;filename="{0}"'.format(file_name.encode("latin-1"))
# response.headers['Content-Disposition'] = 'attachment;filename="{0}"'.format(file_name.encode("iso-8859-1"))
return response

当我把代码再次更新并以gunicorn启动后发现下载文件直接500了,我靠,百思不得其解,难不成gunicorn做了啥额外的配置或者操作?仔细想想gunicorn部署后socket通信应该加了些操作吧(但不知道是具体哪里问题),分析了gunicorn的配置和运行原理没发现通过修改gunicorn设置的解决办法。然而最后阴差阳错的解决了,代码如下:

from urllib.parse import quote

...
file_name = "测试.xlsx"
response.headers['Content-Type'] = 'application/octet-stream'
response.headers['Content-Disposition'] = 'attachment;filename={0};filename*={0}'.format(
quote(file_name))
return response

讲道理这里我都不知道为什么这样能够解决,记录下,以后详细研究。

参考:
https://blog.csdn.net/liuyaqi1993/article/details/78275396
https://segmentfault.com/a/1190000012514419


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM