通过blob对文件预览和下载的处理
最近刚好遇到对pdf文件和zip压缩文件的处理,其实也就是对文件流blob的处理,查阅了一下网上的资料后,顺利的解决,归纳总结一下
一、接口请求设置
由于是封装的axios,需要在接口的请求头header设置返回格式
responseType: "blob"
这样与后端配合可以得到文件流格式的返回
也就是这个样子
二、处理blob文件流数据 ---预览PDF
得到这些乱码的数据后,用createObjectURL处理它
- 通过URL.createObjectURL(blob)可以获取当前文件的一个内存URL
preview(id).then(res => {
let url = window.URL.createObjectURL(new Blob([res], { type: 'application/pdf' }))//获得一个pdf的url对象
window.open(url, '_blank')//打开一个新窗口
URL.revokeObjectURL(url) //释放内存
})
之前没有第三行代码 查了下文档 优化一下性能
内存管理
在每次调用
createObjectURL()
方法时,都会创建一个新的 URL 对象,即使你已经用相同的对象作为参数创建过。当不再需要这些 URL 对象时,每个对象必须通过调用URL.revokeObjectURL()
方法来释放。浏览器在 document 卸载的时候,会自动释放它们,但是为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。
三、处理blob文件流数据 ---下载zip
同上 得到这些乱码的数据后,用createObjectURL处理它
downLoad(id).then((res) => {
const elink = document.createElement('a') //创建个a链接元素
elink.href = window.URL.createObjectURL(new Blob([res], { type: `application/zip` }))//获得一个zip的url对象
elink.style.display = 'none'
elink.setAttribute('download', this.downName) //文件名
document.body.appendChild(elink)
elink.click() //触发点击方法
URL.revokeObjectURL(elink.href) // 释放URL对象
document.body.removeChild(elink) //释放节点
})
与预览相比,多出了创造节点的过程
四、接口下载报错判断及safari浏览器兼容
由于接口返回的是blob流,并且请求头的响应类型设置成了blob responseType: "blob"
所以当后端返回给错误信息时,我们也会将这些信息转化成下载的文件,可以通过对返回的type类型判断
if (!res.type.includes('application/octet-stream')) {
this.$message({
type: 'error',
message: '系统错误,请稍后再试!'
})
return
}
用includes方法是因为在safari浏览器中,type会包含编码类型
五、注意事项及报错
如果打不开这个文件,而postman可以打开,大部分的原因是接口请求没有设置 responseType: "blob"
export function downLoad (checkLogId) {
return request({
url: '*******/',
method: 'get',
responseType: "blob"
})
}
即可