flask下載文件中文IE,Edge,Safari文件名亂碼

flask(0.11.2)+python3.6

  • 兼容各個主流瀏覽器,已通過各類測試(chrome,firefox,safari,IE,Edge)
  • quote是將文件名urlencode化,而後以適應Edge瀏覽器
from urllib.parse import quote  # for python3
# from urllib import quote for python2  
@app.route('/file/download/<filename>', methods=['GET'])
def file_download(filename):
    filename=FILE_PATH+filename
    response = make_response(send_file(filename)) # 
    basename = os.path.basename(filename)
    utf_filename=quote(basename.encode('utf-8')
    response.headers["Content-Disposition"] = "attachment;filename*=UTF-8''{}".format(utf_filename)
    response.headers['Content-Type'] = "application/octet-stream; charset=UTF-8"
    return response
"""
Content-Disposition中的filename進行了兩次URL轉碼。以漢字漫爲例:

第一次轉碼,漫變爲%E6%BC%AB。
第二次轉碼,%E6%BC%AB變爲%25E6%25BC%25AB(第二次轉碼時,由於%是特殊字符,因此會轉爲%25)。
前端下載時:

Chrome瀏覽器能夠自動執行兩次URL解碼,因此下載的文件名是正常的。
IE瀏覽器只執行一次URL解碼,因此下載的文件名是第一次編碼的結果(%E6%BC%AB)(版本8,10驗證問題存在)。
火狐好像也不行。
解決方案是在返回給前端前對Content-Disposition中的filename先進行一次URL解碼(實際我是對filename這個參數進行了解碼,由於文件服務器是用的第三方的。)。

此外,當文件名爲中文(未執行URL編碼)字符串時,IE下載也爲亂碼,由於IE對中文字符串又執行了一次URL解碼。解決方案是將中文字符串進行URL編碼。

因此,總結下來,關鍵的問題就在於IE瀏覽器對filename只進行一次解碼,而chrome對這種狀況是進行了優化的
"""
相關文章
相關標籤/搜索