ajax post下载flask文件流以及中文文件名问题
ajaxpost下载文件
后端返回文件流,flask中可使用returnsend_file(文件路径)返回二进制文件流,在headers中传送文件相关信息(如文件名)。
前端使用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)
中文文件名乱码
httpheaders中直接传输中文文件名,比较简单的方法是后端进行url转码(这里使用python的urllib.parse.quote),前端使用decodeURI()解码。
此外还可以设置headers的Content-Disposition:attachment;filename*=UTF-8''xxxxx,不过兼容性嘛……麻烦还不如直接urlcode算了,而且也懒得设置Content-Disposition了,前端从Content-Disposition中取filename也是够麻烦的,会取到一长串字符串然后自己再想办法取出来filename=后面的信息。
代码如下:
flask
fromurllib.parseimportquote
@file.route('/download',methods=["POST"])
defdownload_file():
filename='xx'#文件名
filepath='xx/xx'#文件路径
res=make_response(send_file(filepath))
#自定义的一个header,方便前端取到名字
res.headers['filename']=quote(filename.encode('utf-8'))
returnres
javascript——以async异步fetch为例:
asyncfunctiondownload(){
constres=awaitfetch(`http://xxx/file/download`,{
method:"POST",
body:JSON.stringify({}),//body里面是要发送的数据
headers:{"Content-Type":"application/json"},
responseType:'blob'
})
if(res.ok){
constblData=awaitres.blob()//拿到blob数据
consturlObjData=window.URL.createObjectURL(newBlob([blData]))//创建url对象
//获取文件进行下转码
constfileName=decodeURI(fileNameres.headers.get('filename'))
//创建a标签点击a标签达到下载目的
constlink=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:
下载
py:
@app.route('/downloadfile/',methods=['GET','POST'])
defdownloadfile():
ifrequest.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'))
#returnsend_from_directory(filepath,filename,as_attachment=True)
#流式读取
defsend_file():
store_path=fullfilename
withopen(store_path,'rb')astargetfile:
while1:
data=targetfile.read(20*1024*1024)#每次读取20M
ifnotdata:
break
yielddata
response=Response(send_file(),content_type='application/octet-stream')
response.headers["Content-disposition"]='attachment;filename=%s'%filename#如果不加上这行代码,导致下图的问题
returnresponse
没有文件名,和文件格式,遇到这种情况,打开F12,查看response.headers与正常的比较
总结
到此这篇关于ajaxpost下载flask文件流以及中文文件名的文章就介绍到这了,更多相关ajaxpost下载flask文件流内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!