前端下载文件一般是一个a标签跳转链接到以上传文件服务器的文件,浏览器自动生成下载,或者是点击直接a标签生成文件流直接下载,但是后面这种如果后端报错,前端不能对报错信息进行处理的情况下,会将数据直接打印在页面上,这样子就特别影响到用户体验。这边我们ajax请求数据,尽量报错信息能使前端捕获到,那就数据流要在前端进行处理,那么和后端约定传过来的流格式目前归纳为两种:
1.base64数据传输生成链接:
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if ( xhr.readyState === 4 ) {
if (xhr.status === 200) {
try {
//传过来的数据
var feedbackData = JSON.parse(xhr.responseText);
var a = document.createElement('a');
//生成a标签链接
a.href = 'data:application/pdf;base64,' + feedbackData.data;
//下载文件名,不加是自定义
a.setAttribute('download', 'pdf下载.pdf');
//自动下载
a.click();
} catch(e) {
self.opt.warnCallback && self.opt.warnCallback.call(this, "请求错误");
}
} else {
console.log("当前状态" + xhr.status)
}
}
}
xhr.open('get', url, false);
xhr.send('');
2.二进制生成链接
(1)组装blob对象
(2)createObjectURL(blob)生成对象
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if ( xhr.readyState === 4 ) {
if (xhr.status === 200) {
try {
//传过来的数据
var feedbackData = JSON.parse(xhr.responseText);
//生成类型数组视图
var byteString = feedbackData.data,
UnitArray = new Uint8Array(byteString.length);
for(var i = 0; i < byteString.length; i++) {
UnitArray[i] = byteString.charCodeAt(i);
};
//组装blob,类file
var blob = new Blob( [UnitArray], { type: 'application/pdf'});
var url = URL.createObjectURL(blob);
var a = document.createElement('a');
a.download='pdf下载.pdf';
a.href = url;
//自动下载
a.click();
} catch(e) {
self.opt.warnCallback && self.opt.warnCallback.call(this, "请求错误");
}
} else {
console.log("当前状态" + xhr.status)
}
}
}
xhr.open('get', url, false);
xhr.send('');
上面的也可以第一种也可以将base64先转化成二进制(btoa生成二进制),在生成blob对象,在生成链接;也可以将二进制转化成base64,在生成本地链接,排除为了兼容,谁会去舍近求远呢?有一种场景就是cavas图片上传,文件服务器只接受文件格式,那么canvas上传就要先把转化成base64,再将base64转化成二进制,生成blob对象,再上传。这边不详细说明了。
网友评论