背景交代:
--由于之前后端在弄其他项目,于是前端先行,由于没有接口数据,习惯性的去使用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的全局注入
恍然大悟: 就算你的axios 也好,还是ajax请求,也好,都是基于xmlHttpRequest原理的,但是如果你全局引入了mnck,那么发送的网络请会被mock监听,并且如果有原生的XMLHttpRequest请求都会被劫持替换,所以你使用axios或者ajax设置的responseType == blob, 就等于没有设置,因为Mock中的responseType默认是空,所有只要mock孩还在,你就永远无法给返回头设置类型,导致返回的blob数据为乱码,从而导致下载失败而且成因很难排查。
在main.js中注释,重启即可。
// import '@/mock/index'
最后也有在网上看到可以修改mock源码,手动给MockHttpRequest 挂载上responseType 属性!!!