後端返回文件流,flask中可以使用return send_file(文件路徑)
返回二進制文件流,在headers中傳送文件相關信息(如文件名)。javascript
前端使用URL.createObjectURL()建立建立一個 DOMStringURL對象,建立一個a
節點,將URL對象賦給a節點的href
屬性,最後調用click()
方法點擊該a
節點便可彈出瀏覽器下載框。前端
方法同上,將a
改爲img
,href
改爲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 } }