axios方式
利用window.URL.createObjectURL
axios.request({
method: 'post',
data: params,
url: '....',
reponseType: 'blob' // 作用:后端返回的就是blob对象,所以不用在new Bolb创建了
}).then(res=>{
const blob = res.data // res.data就是Blob对象
const URL = window.URL.createObjectURL(blob) // 参数:blob/file
const filename = decodeURI(res['headers']['content-disposition'].split('filename=')[1]) || (new Date().getTime()) + '.xls' // 获取filename
const a = focument.createElement('a')
a.href = URL
a.click()
window.URL.revokeObjectURL(URL) //不用了必须释放URL对象
})
FileReader方式
axios.request({
method: 'post',
data: params,
url: '....',
reponseType: 'blob' // 作用:后端返回的就是blob对象,所以不用在new Bolb创建了
}).then(res=>{
const blob = res.data
const fileReader = new FileReader()
// 参数:blob/file,读取完成后,触发loadend事件,同时 result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容,result 属性值可作为 DOM 元素的 src 属性
fileReader.readAsDataURL(blob)
fileReader.onload = (eve)=>{ // readAsDataURL后监听load事件,读取base64编码文件字符串下载
const filename = decodeURI(res['headers']['content-disposition'].split('filename=')[1]) || (new Date().getTime()) + '.xls' // 获取filename
const a = document.createElement('a')
a.download = filename
a.href = eve.target.result
document.appendChild(a)
a.click()
document.removeChild(a)
}
})
FileReader.readAsDataURL(blob)与URL.createObjectURL(blob)对比
-返回值
FileReader.readAsDataURL(blob)可以得到一段base64编码的字符串,可以在eve.target.result获取,作为a标签的href,如下图
URL.createObjectURL(blob)得到的是当前文件的一个内存url,如下图
-内存清理
FileReader.readAsDataURL(blob)依照js垃圾回收机制自动从内存中清理,因为它相当于一个JS对象
URL.createObjectURL(blob)存在于document内,清除方式只有upload()事件或者revokeObjectURL()手清除
-执行方式
FileReader.readAsDataURL(blob)触发loadend事件,需要监听load事件去执行相应回掉函数,属于异步执行
URL.createObjectURL(blob) 直接返回内存URL,同步执行
-多文件处理
FileReader.readAsDataURL(blob)同时处理多个文件时,每个fileReader对象只能处理一个bolb/file文件,需要一个文件对应一个FileReader对象
URL.createObjectURL(blob)直接处理多个blob即可,没有任何影响
使用中遇到的坑
1.执行之后发现下载的文件打开报文件格式与文件名不匹配,已损坏,打开乱码,经查阅资料发现是使用了mockJS测试,在main.js内去掉就可以了
2.上面执行报错
有时候出现:Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob',这种情况是由于后端返回的不是个Blob对象,如下:
所以需要自己构建再使用,Blob对象如下:
const blob = new Blob([res.data])