先说结论,再说细节:前端axiosconfig配置responseType:'blob'(key)服务端读取文件并以content格式返回-type:'application/octet-stream'前端接收到数据后,使用Blob接收数据,创建tag下载。前端发起请求。在使用axios发起请求前,先了解一下axios中responseType属性是如何使用的。以axios最常用的get和post请求为例。这两种请求方式在传递参数的时候也是不一样的。使用的版本axios@0.19.2如何传递responseType?文件:lib/core/Axios.js结论:您可以看到axios以不同方式处理get和post请求。在get请求中,config是第二个参数,在post中,config成为第三个参数,这是传递responseType时首先要注意的一点。为什么要传递responseType?文件:lib/adapters/xhr.js结论:默认情况下,config.responseType是未定义的,所以通常情况下,我们得到的response中的数据一定是字符串对象request.responseText。但是对于文件下载,我们后面需要用到request.response对象,这也是为什么要传递responseType的原因。为什么responseType是“blob”?来源:mdn中xhr.response属性介绍结论:可以看到,response返回的数据格式是由responseType决定的,因为我们需要在回调中使用Blob构造函数来接收数据,所以我们传递的responseType应该也可以是'blob',保证数据格式的统一//通过以上几点,那么对于axios来说,设置responseType的方式应该类似于下面的consturl='/info/download'//get,delete,head和其他请求axios.get(url,{params:{...someParmas},responseType:'blob'}).then((res)=>{//...}).catch((err)=>{//})//post、put、patch和其他请求axios.post(url,{...someData},{responseType:'blob'}).then((res)=>{//...}).catch((err)=>{//})服务端如何返回数据//下面是express的例子constfs=require('fs')constexpress=require('express')constbodyParser=require('body-parser')constapp=express()app.use(bodyParser.urlencoded({extended:false}))app.use(bodyParser.json())//post提交的例子app.post('/info/download',function(req,res){constfilePath='./file/test.jpeg'constfileName='test.jpeg'res.set({'content-type':'application/octet-stream','content-disposition':'attachment;filename='+encodeURI(fileName)})fs.createReadStream(filePath).pipe(res)})app.listen(3000)结论:使用express模拟请求下载接口。返回流文件时,只需要统一设置content-type:'application/octet-stream'即可,不需要针对不同的文件类型进行不同的设置。content-disposition的content-type,在为content-disposition设置文件名时,需要对文件名进行转码,防止下载的文件名中有汉字时出现乱码。前端解析数据流前端解析数据流,主要是利用Blob对象接收//以之前的post请求为例axios.post(url,{...someData},{responseType:'blob'}).then((res)=>{const{data,headers}=resconstfileName=headers['content-disposition'].replace(/\w+;filename=(.*)/,'$1')//这里,返回json文件需要先对数据进行JSON.stringify处理,其他类型的文件不需要处理//constblob=newBlob([JSON.stringify(data)],...)constblob=newBlob([data],{type:headers['content-type']})letdom=document.createElement('a')leturl=window.URL.createObjectURL(blob)dom.href=urldom.download=decodeURI(fileName)dom.style.display='none'document.body.appendChild(dom)dom.click()dom.parentNode.removeChild(dom)window.URL.revokeObjectURL(url)}).catch((err)=>{})结论:使用Blob解析返回的流,在下载前使用URL.createObjectURL将blob转化为url,下载完成后释放url。剩下的常见情况就是后台返回的流文件是图片。那么如何在前端显示这张图片,代码大概如下axios.post(url,{...someData},{responseType:'blob'}).then((res)=>{const{data}=resconstreader=newFileReader()reader.readAsDataURL(data)reader.onload=(ev)=>{constimg=newImage()img.src=ev.target.resultdocument.body.appendChild(img)}}).catch((err)=>{})结论:使用FileReader对象读取流文件,并对文件进行解析它变成一个base64链接,最后将img指向这个链接
