今日在开发一个导出功能,原本一个非常简单的功能,却没想里面藏了陷阱!
背景
前端导出的文件流乱码,此时确定非后端问题(可以在postman导出是否正常来判断)。
前端导出:
后端正常数据:
答疑
第一,如果你要做一个导出功能(后端返回的数据位文件流),那接口可能是类似的结构
红框为必不可少的参数,且与其他参数同级,如“data”,“headers”等,如果你没有,那“还没开始就已经结束了”。
第二,前端导出代码可能是类似的结构,网上代码大同小异
对于红框部分,我在测试导出的过程中, 有跟没有乱码结果是一样的,因为这个不是决定性因素(前提是后端返回的数据为utf-8格式的文件流)。
以上两点,在后端返回正常的文件流情况下,前端导出基本是没什么问题的。
但是!如果此时你导出的文件还是出现了乱码,那就需要更深入排查了。
在参考了大部分对于该问题的应对文章后,我总算是找到了解决方案!
深入排查
首先,排查返回的数据响应头数据结构,可在响应拦截器中打印出来,查看“request”中的“response”与“responseType”
如果出现了以上情况,“responseType”是空的,“response”(即“data”)不是blob对象而是一个字符串,这就有问题了。
正常来说,前端响应接收到应该是一个blob对象,类似
针对这个问题,我排查了蛮久,明明自己在请求接口加了参数 responseType: 'blob'
为啥响应体该字段是空?且返回数据不是blob对象?
在参考了多篇博客,经过仔细排查之后,发现一个问题,就是我项目中使用了“mock”,没错,就是可以劫持请求的那个“mock”!也正是因为它,将我的“responseType”置空!如下:
vue.config.js 配置:
(此时process.env.VUE_APP_BUILD_MODE不是“nomock”,导致使用“mock”)
mock 配置:
(此时responseType: ' ',)
我尝试把使用“mock”的地方注释掉:
重启,导出,成功!!!
响应体也不吃意外的同步
总结
1、请求参数 responseType: 'blob'
2、new Blob([res], {type:"application/vnd.ms-excel;charset=UTF-8"})
3、移除“mock”,避免对请求进行劫持从而影响参数