域名預(yù)訂/競(jìng)價(jià),好“米”不錯(cuò)過(guò)
這篇文章主要介紹了ajax post下載flask文件流以及中文文件名問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
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 ,不過(guò)兼容性嘛……麻煩還不如直接urlcode算了,而且也懶得設(shè)置 Content-Disposition 了,前端從 Content-Disposition 中取 filename 也是夠麻煩的,會(huì)取到一長(zhǎng)串字符串然后自己再想辦法取出來(lái) 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" class="btn btn-success pull-right" 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)文章希望大家以后多多支持腳本之家!
來(lái)源:腳本之家
鏈接:https://www.jb51.net/article/184005.htm
申請(qǐng)創(chuàng)業(yè)報(bào)道,分享創(chuàng)業(yè)好點(diǎn)子。點(diǎn)擊此處,共同探討創(chuàng)業(yè)新機(jī)遇!