前端处理blob实现预览pdf和下载zip

5,540 阅读2分钟

通过blob对文件预览和下载的处理

最近刚好遇到对pdf文件和zip压缩文件的处理,其实也就是对文件流blob的处理,查阅了一下网上的资料后,顺利的解决,归纳总结一下

一、接口请求设置

由于是封装的axios,需要在接口的请求头header设置返回格式 responseType: "blob" 这样与后端配合可以得到文件流格式的返回 也就是这个样子 image.png

二、处理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"
  })
}

即可