ajax post下載flask文件流以及中文文件名

  • ajax post下載文件

    後端返回文件流,flask中可以使用return send_file(文件路徑)返回二進制文件流,在headers中傳送文件相關信息(如文件名)。javascript

    前端使用URL.createObjectURL()建立建立一個 DOMStringURL對象,建立一個a節點,將URL對象賦給a節點的href屬性,最後調用click()方法點擊該a節點便可彈出瀏覽器下載框。前端

  • 展現圖片

    方法同上,將a改爲imghref改爲src便可,將URL對象寫入到目標img標籤的src便可。
    另外一種方法是後端返回圖片轉base64的字符串,src的值形如"data:image/svg+xml;base64,${base字符串}"。(這裏的svg+xml表示圖片格式是svg,若是是png則改爲png)java

  • 中文文件名亂碼

    http headers中直接傳輸中文文件名,比較簡單的方法是後端進行url轉碼(這裏使用python的urllib.parse.quote),前端使用decodeURI()解碼。
    此外還能夠設置headers的Content-Disposition: attachment; filename*=UTF-8''xxxxx,不過兼容性嘛……麻煩還不如直接urlcode算了,並且也懶得設置Content-Disposition了,前端從Content-Disposition中取filename也是夠麻煩的,會取到一長串字符串而後本身再想辦法取出來filename=後面的信息。python

代碼以下:ajax

flaskjson

from urllib.parse import quote
@file.route('/download', methods=["POST"])
def download_file():
    filename='xx' #文件名
    filepath='xx/xx'  #文件路徑
    res = make_response(send_file(filepath))
    #自定義的一個header,方便前端取到名字
    res.headers['filename'] = quote(filename.encode('utf-8'))
    return res

javascript——以async異步fetch爲例:flask

async function download() {
    const res = await fetch(`http://xxx/file/download`, {
    method: "POST",
    body: JSON.stringify({}),  //body裏面是要發送的數據
    headers: { "Content-Type": "application/json" },
    responseType: 'blob'
  })

  if (res.ok) {
    const blData = await res.blob()  //拿到blob數據
    const urlObjData = window.URL.createObjectURL(new Blob([blData]))  //建立url對象
    
    //獲取文件 進行下轉碼
    const fileName = decodeURI(fileNameres.headers.get('filename'))
    
    //建立a標籤 點擊a標籤 達到下載目的
    const link = document.createElement('a')
    link.href = urlObjData
    link.download = fileName //下載文件的名字
    document.body.appendChild(link)
    link.click()
    
    document.body.removeChild(link)
    window.URL.revokeObjectURL(urlObjData);
    
    //展現圖片
    //xxx.src=urlObjData
  }
}
相關文章
相關標籤/搜索