先说结论
如果你在用ajax接口接收文件时遇到文件保存后打开报错的情况,请尝试在请求header头中加入responseType: arraybuffer
排坑过程
最近在对接前后端文件传输接口时遇到的问题,后端返回xlsx文件,前端使用new blob()
方法从接口返回的数据中重新生成文件。但是
生成的文件用excel打开总是报错。尝试在浏览器或Postman中调用接口保存文件都没有问题。
一开始各种尝试改变new blob
方法的type参数没有效果。查看blob方法文档,
最坑的就是这里Blob(blobParts[, options])
blobParts what fuck is blobParts? 文档中给出的示例有new Blob([JSON.stringify(debug, null, 2),{type : 'application/json'});
so 一个包含字符串的数组?还有一段从blob中读取数据reader.readAsArrayBuffer(blob);
可以看出这里读出的数据应该是arraybuffer。
再看一下XMLHttpRequest.responseType的官方文档
arraybuffer的解释 是一个包含二进制数据的 JavaScript ArrayBuffer 。另外我在另一篇Creating a Blob from a base64 string in JavaScript
的提问中当中看到有高手给出的答案中指出了,想要得到blob你先要得到ArrayBuffer, text, and JSON
结论
到这里我们基本已经得到答案了,生成blob对象进而生成文件我们需要ArrayBuffer, text, or JSON这种三种数据类型的某一种。
测试验证
后端Java,代码当中使用的是 BufferedOutputStream
类来返回数据。前端分别测试了”json””text”””arraybutter””blob”四种responseType
arraybutter和blob都可以正确的生成文件。
参考文章
MDN解释
java io系列12之 BufferedInputStream(缓冲输入流)的认知、源码和示例
深入理解xhr的responseType中blob和arrayBuffer