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