ajax post下載flask文件流以及中文文件名問題
ajax post下載文件
后端返回文件流,flask中可使用 return send_file(文件路徑) 返回二進制文件流,在headers中傳送文件相關信息(如文件名)。
前端使用 URL.createObjectURL() 創建創建一個 DOMString URL對象,創建一個 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)
中文文件名亂碼
http headers中直接傳輸中文文件名,比較簡單的方法是后端進行url轉碼(這里使用python的 urllib.parse.quote ),前端使用 decodeURI() 解碼。
此外還可以設置headers的 Content-Disposition: attachment; filename*=UTF-8""xxxxx ,不過兼容性嘛……麻煩還不如直接urlcode算了,而且也懶得設置 Content-Disposition 了,前端從 Content-Disposition 中取 filename 也是夠麻煩的,會取到一長串字符串然后自己再想辦法取出來 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))
#自定義的一個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里面是要發送的數據
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
}
}
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 # 如果不加上這行代碼,導致下圖的問題
return response
沒有文件名,和文件格式,遇到這種情況,打開F12,查看response.headers 與正常的比較
總結
到此這篇關于ajax post下載flask文件流以及中文文件名的文章就介紹到這了,更多相關ajax post下載flask文件流內容請搜索以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持!
相關文章:

網公網安備