文件下载与mockjs的情仇,有你没我?

121 阅读2分钟

背景交代:

--由于之前后端在弄其他项目,于是前端先行,由于没有接口数据,习惯性的去使用mockjs,去模拟一些接口,返回假数据用于先将页面的效果做出来,一切看似都没有什么问题,就算是导入了真实接口我也没去管全局注入的mock实例。

--直到遇到了文件下载这个功能。。。

  • 我发现如果是pdf,那么后端返回的数据,前端下载,一定是会是空白的pdf

  • 如果是word,那么必定打开报错文件损坏

于是开始上下而求索:

找寻到的方案一:

blob 没有设置相应的传mimeType文件流格式: 比如 excel =》 application/vnd.ms-excel  word => application/msword  

const download = (data: Blob, fileName: string, mineType: string) => {
  // 创建 blob
  const blob = new Blob([data], { type: mineType }) // 传入相应的mimeType
  // 创建 href 超链接,点击进行下载
  window.URL = window.URL || window.webkitURL
  const href = URL.createObjectURL(blob)
  const downA = document.createElement('a')
  downA.href = href
  downA.download = fileName
  downA.click()
  // 销毁超连接
  window.URL.revokeObjectURL(href)
}
 

方案二:没有设置responseType==blob|arraybuffer


 download: async <T = any>(option: any) => {
 
    const res = await request({ method: 'GET', responseType: 'blob', ...option })
    return res as unknown as Promise<T>
  }

方案三: 后端排查是否真的是返回格式有误

方案四:最后一种也是最容易被忽视的,也是最隐蔽的,都是mockjs的全局注入

image.png

恍然大悟: 就算你的axios 也好,还是ajax请求,也好,都是基于xmlHttpRequest原理的,但是如果你全局引入了mnck,那么发送的网络请会被mock监听,并且如果有原生的XMLHttpRequest请求都会被劫持替换,所以你使用axios或者ajax设置的responseType == blob, 就等于没有设置,因为Mock中的responseType默认是空,所有只要mock孩还在,你就永远无法给返回头设置类型,导致返回的blob数据为乱码,从而导致下载失败而且成因很难排查。

在main.js中注释,重启即可。

// import '@/mock/index'

最后也有在网上看到可以修改mock源码,手动给MockHttpRequest 挂载上responseType 属性!!!

image.png