最近碰到一个需求,需要在页面提供导出按钮下载压缩文件,后台是以文件流的形式返回给前端,在出错的时候返回错误信息给前端,由于使用jquery封装的ajax请求中并不提供文本类型 ,决定使用js原生请求来做,特此记录一下.
var url = xxx
$("#endDate").val() + "&&state=3" ;
var xhr = new XMLHttpRequest();
//封装请求(请求方式, 请求路径, 是否异步)
xhr.open('GET', url, true);
xhr.setRequestHeader("Authorization", "Bearer " + sessionStorage.getItem("token"));
//返回类型(blob是二进制大文件类型)
xhr.responseType = "blob";
xhr.onload = function () {
//通过状态处理请求
if (this.status === 200) {
var name = xhr.getResponseHeader("Content-Disposition");
var filename = name.substring(20,name.length);
var blob = new Blob([xhr.response], {type: 'application/octet-stream'});
var csvUrl = URL.createObjectURL(blob);
//模拟a标签下载文件
var link = document.createElement('a');
link.href = csvUrl;
link.download = filename;
link.click();
}else if(this.status === 5001){
bootbox.alert("日期格式错误");
}else if(this.status === 5000){
bootbox.alert("没有订单数据");
}
};
开发过程中遇到的问题
下载的压缩文件不能打开
没有指定返回类型,下载过程中文件被损坏
如何接受后台返回的错误信息
由于返回类型指定为BLOB,无法读取到responseText的信息,所以采用后台返回不同的response.status来区分不同错误
兼容火狐浏览器
//之前的代码在火狐浏览器下不能兼容,修改后如下
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.setRequestHeader("Authorization", "Bearer " + sessionStorage.getItem("token"));// 也可以使用POST方式,根据接口
xhr.responseType = "blob";
xhr.onload = function () {
if (this.status === 200) {
var name = xhr.getResponseHeader("Content-Disposition");
var filename = name.substring(20, name.length);
var blob = new Blob([xhr.response], {type: 'application/octet-stream'});
var csvUrl = URL.createObjectURL(blob);
var link = document.createElement('a');
link.setAttribute("href", csvUrl);
link.setAttribute("download", filename);
var evt = document.createEvent("MouseEvents");
evt.initEvent("click", false, false);
link.dispatchEvent(evt);
}else if(this.status === 5001){
bootbox.alert("日期格式错误");
}else if(this.status === 5000){
bootbox.alert("没有订单数据");
}else if(this.status === 5002){
bootbox.alert("获取网点信息出错");
}else{
bootbox.alert("导出失败");
}
};
// 发送ajax请求
xhr.send();