之前因为懒,异步请求的下载都是直接写在a标签里,请求权限让后端做特殊处理判断,就像这样
<a href="getRequestUrl">点击下载</a>
现在觉得这样处理不太好,一个是后端权限要做单独判断,另一个是如果调用接口报错就没办法处理了,研究之后修改了一下,项目用了axios这个lib,所以是针对axios的request和response做了修改,不过对于原生写法和其他库,原理是一样的

1.将请求的responseType设置为blob

function exportData(p) {    return axios({        url: '/data/export',        method: 'get',        params: p,        responseType: 'blob'    });}

2.对response进行处理

因为项目里用了response拦截器来处理响应,所以我在拦截器里做了处理,也可以单独处理。

axios.interceptors.response.use(    response=> {        // ...        // Blob类型处理        let checkType = response.config.responseType;        if(checkType === "blob" && res.type === 'application/octet-stream') { // 正常下载时直接返回响应数据            return response.data        } else if(checkType === "blob" && res.type === 'application/json') { // 请求出错时,接口返回的内容是json,于是将blob中的内容取出            let reader = new FileReader();            reader.onload = function(event){                let content = reader.result; // blob中的内容                Message({                    message: JSON.parse(content).desc,                    type: 'error',                    duration: 5 * 1000                })            };            reader.readAsText(response.data);            return Promise.reject('error')        }                // ...    },    error => {        // ...    })

3.html页面自动开始下载

exportData(para).then(res => {    let content = res;    let aTag = document.createElement('a');    let blob = new Blob([content]);    aTag.download = 'Datas.xlsx'; // 也可以让后端设置文件名,通过headers返回    aTag.href = URL.createObjectURL(blob);    aTag.click();    URL.revokeObjectURL(blob);}).finally(() => {})
参考博客:https://www.cnblogs.com/coder...