ajax处理下载文件请求
前言
碰到了一个前端的小问题,django后端提供了一个下载文件的接口,前端页面点击下载,通过window.location.href,就能直接下载到本地,但是当接口内部查询失败,则会通过json格式返回报错信息。这样就会出现一个问题,虽然用页面跳转的方式下载文件很方便,但是出现报错信息的时候会给你跳转到一个新的带json数据的页面,很明显,这对于用户体验是非常糟糕的!
实现
所以接下来的思路就是既能让接口返回文件数据的时候进行下载,又能在返回json信息的时候弹窗提示。
那么我首先想到的就是用ajax了,平时一般都使用jquery来发送ajax,但是这里就会出现一个很致命的问题,如果将ajax的接收数据类型设为json或者不设置,那么json数据能正常获取,但是获得文件返回的数据流下载到本地时,内容很明显产生了偏差。如果设置为blob类型,我就获取不到json格式数据。而且用jquery封装的ajax貌似不好获取返回数据的类型用于判断,所以暂时放弃。
不过在网上了解到了原生js发送ajax请求的方式,将返回数据都接受为blob类型,然后就能获取数据的响应头的数据类型,进而判断应该执行下载代码还是弹窗提示,当然在进入json格式部分时,还需要处理一道,把blob转换成json数据,到此就能正常获取异常信息了。代码如下:
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true); // 也可以使用POST方式,根据接口
xhr.responseType = "blob"; // 返回类型blob
xhr.onload = function () {
// 请求完成
if (this.status === 200) {
// console.log(this.response)
let res_type = this.response.type
if (res_type == 'application/octet-stream') {
var blob = this.response;
var reader = new FileReader();
reader.readAsDataURL(blob); // 转换为base64
reader.onload = function (e) {
// 转换完成,创建一个a标签用于下载
var a = document.createElement('a');
let file_name = "file_name.bin"
a.download = file_name;
a.href = e.target.result;
$("body").append(a); // 修复firefox中无法触发click
a.click();
$(a).remove();
}
} else if (res_type == "application/json") {
// blob转json,获取异常信息
var enc = new TextDecoder('utf-8');
this.response.arrayBuffer().then(buffer = > {
let data = JSON.parse(enc.decode(new Uint8Array(buffer))) || {};
// console.log(data)
layer.msg(data['msg'])
}
)
}
} else {
layer.msg("请求异常!")
}
};
// 发送ajax请求
xhr.send()

浙公网安备 33010602011771号