最近有个需求,从服务器下载数据表格,存储到本地,过程中发现excel保存不成功,最后发现是responseType未设置正确。
responseType是什么?
XMLHttpRequest.responseType 属性是一个枚举类型的属性,设置返回响应数据的类型。
当将responseType设置为一个特定的类型时,你需要确保服务器所返回的类型和你所设置的返回值类型是兼容的。
responseType支持以下几种值:
key | 含义 |
---|---|
“” | responseType 为空字符串时,采用默认类型 DOMString,与设置为 text 相同。 |
arraybuffer | response 是一个包含二进制数据的 JavaScript ArrayBuffer。 |
blob | response 是一个包含二进制数据的 Blob 对象 。 |
document | response 是一个 HTML Document 或 XML XMLDocument,这取决于接收到的数据的 MIME 类型。 |
json | response 是一个 JavaScript 对象。这个对象是通过将接收到的数据类型视为 JSON 解析得到的。 |
text | response 是一个以 DOMString 对象表示的文本。 |
ms-stream | response 是下载流的一部分;此响应类型仅允许下载请求,并且仅受 Internet Explorer 支持。 |
正确的获取文件流并保存的方式
XHR的responseText的类型为DOMString,只有当responseType为DOMString时才有正确数据,其他类型获取响应实体用xhr.response。
let url = '/detial/downLoadDetial';
let xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.responseType = 'blob' ; //arraybuffer也可以
xhr.ontimeout = ()=>{};
xhr.onreadystatechange=()=>{
if(xhr.readyState === 4) {
if(xhr.status =200) {
let res = xhr.response; //不是responseText。
let blob = new Blob([res]);
var reader = new FileReader(); // 是一个对象,其唯一目的是从 Blob(因此也从 File)对象中读取数据。
reader.readAsDataURL(blob); // 转换为base64,可以直接放入a标签href
reader.onload = (e) => {
// 转换完成,创建一个a标签用于下载
var a = document.createElement("a");
a.download = "导出.xls";
a.href = e.target.result;
document.body.appendChild(a);
a.click();
setTimeout(function(){
document.body.removeChild(a);
}, 200)
};
//Videos on Android do not play when the src is set as a blob via create URL, 在移动端有兼容问题
};
}
};
参考:https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader
https://developer.mozilla.org/zh-CN/docs/Web/API/Blob
https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/responseType
https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest