ajax post下載flask文件流以及中文文件名問題
ajax post下載文件
后端返回文件流,flask中可使用 return send_file
(文件路徑) 返回二進(jìn)制文件流,在headers中傳送文件相關(guān)信息(如文件名)。
前端使用 URL.createObjectURL() 創(chuàng)建創(chuàng)建一個(gè) DOMString URL對(duì)象,創(chuàng)建一個(gè) a 節(jié)點(diǎn),將URL對(duì)象賦給a節(jié)點(diǎn)的 href 屬性,最后調(diào)用 click() 方法點(diǎn)擊該 a 節(jié)點(diǎn)即可彈出瀏覽器下載框。
展示圖片
方法同上,將 a 改成 img , href 改成 src 即可,將URL對(duì)象寫入到目標(biāo)img標(biāo)簽的src即可。
另一種方法是后端返回圖片轉(zhuǎn)base64的字符串,src的值形如 "data:image/svg+xml;base64,${base字符串}"
。(這里的 svg+xml 表示圖片格式是svg,如果是png則改成png)
中文文件名亂碼
http headers中直接傳輸中文文件名,比較簡(jiǎn)單的方法是后端進(jìn)行url轉(zhuǎn)碼(這里使用python的 urllib.parse.quote ),前端使用 decodeURI()
解碼。
此外還可以設(shè)置headers的 Content-Disposition: attachment; filename*=UTF-8""xxxxx
,不過兼容性嘛……麻煩還不如直接urlcode算了,而且也懶得設(shè)置 Content-Disposition 了,前端從 Content-Disposition
中取 filename 也是夠麻煩的,會(huì)取到一長(zhǎng)串字符串然后自己再想辦法取出來 filename= 后面的信息。
代碼如下:
flask
from urllib.parse import quote @file.route("/download", methods=["POST"]) def download_file(): filename="xx" #文件名 filepath="xx/xx" #文件路徑 res = make_response(send_file(filepath)) #自定義的一個(gè)header,方便前端取到名字 res.headers["filename"] = quote(filename.encode("utf-8")) return res javascript——以async異步fetch為例: async function download() { const res = await fetch(`http://xxx/file/download`, { method: "POST", body: JSON.stringify({}), //body里面是要發(fā)送的數(shù)據(jù) headers: { "Content-Type": "application/json" }, responseType: "blob" }) if (res.ok) { const blData = await res.blob() //拿到blob數(shù)據(jù) const urlObjData = window.URL.createObjectURL(new Blob([blData])) //創(chuàng)建url對(duì)象 //獲取文件 進(jìn)行下轉(zhuǎn)碼 const fileName = decodeURI(fileNameres.headers.get("filename")) //創(chuàng)建a標(biāo)簽 點(diǎn)擊a標(biāo)簽 達(dá)到下載目的 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 } }
ps:flask下載文件---文件流
html:
<a name="downloadbtn" href="/downloadfile/?filename=/root/allfile/123.txt">下載</a>
py:
@app.route("/downloadfile/", methods=["GET", "POST"]) def downloadfile(): if request.method == "GET": fullfilename = request.args.get("filename") # fullfilename = "/root/allfile/123.txt" fullfilenamelist = fullfilename.split("/") filename = fullfilenamelist[-1] filepath = fullfilename.replace("/%s"%filename, "") #普通下載 # response = make_response(send_from_directory(filepath, filename, as_attachment=True)) # response.headers["Content-Disposition"] = "attachment; filename={}".format(filepath.encode().decode("latin-1")) #return send_from_directory(filepath, filename, as_attachment=True) #流式讀取 def send_file(): store_path = fullfilename with open(store_path, "rb") as targetfile: while 1: data = targetfile.read(20 * 1024 * 1024) # 每次讀取20M if not data: break yield data response = Response(send_file(), content_type="application/octet-stream") response.headers["Content-disposition"] = "attachment; filename=%s" % filename # 如果不加上這行代碼,導(dǎo)致下圖的問題 return response
沒有文件名,和文件格式,遇到這種情況,打開F12,查看response.headers 與正常的比較
總結(jié)
到此這篇關(guān)于ajax post下載flask文件流以及中文文件名的文章就介紹到這了,更多相關(guān)ajax post下載flask文件流內(nèi)容請(qǐng)搜索以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持!
相關(guān)文章:
1. 解決ajax的delete、put方法接收不到參數(shù)的問題方法2. SpringMVC+Jquery實(shí)現(xiàn)Ajax功能3. 一篇文章弄清楚Ajax請(qǐng)求的五個(gè)步驟4. 使用FormData進(jìn)行Ajax請(qǐng)求上傳文件的實(shí)例代碼5. laravel ajax curd 搜索登錄判斷功能的實(shí)現(xiàn)6. Ajax實(shí)現(xiàn)表格中信息不刷新頁面進(jìn)行更新數(shù)據(jù)7. 告別AJAX實(shí)現(xiàn)無刷新提交表單8. Ajax引擎 ajax請(qǐng)求步驟詳細(xì)代碼9. ajax請(qǐng)求后臺(tái)得到j(luò)son數(shù)據(jù)后動(dòng)態(tài)生成樹形下拉框的方法10. 爬取今日頭條Ajax請(qǐng)求
