获取数据都知道,使用的是 axios,主要是设置 responseType: 'blob'
由于项目使用的是 apipost ,所以在使用的时候还要设置 isReturnNativeResponse -是否返回本机响应标头,一般可能设置 responseType: 'blob' 就可以了
export function getDownZip(params?: object) {
return defHttp.get(
{ url: Api.downZip, params: params, responseType: 'blob' },
{ isTransformResponse: false, isReturnNativeResponse: true },
);
}
通过上面接口返回的数据就能直接使用下面方法下载
/**
* result.data 是对应的文件,具体的看返回数据,不一定存放在data中
* 名称
* 后缀名
*/
async function getData() {
const result = await getDownZip({});
downloadByData(result.data, '测试', 'application/json');
}
/**
* 根据后台接口文件流下载
* @param {*} data
* @param {*} filename
* @param {*} mime
* @param {*} bom
*/
export function downloadByData(data: BlobPart, filename: string, mime?: string, bom?: BlobPart) {
const blobData = typeof bom !== 'undefined' ? [bom, data] : [data];
const blob = new Blob(blobData, { type: mime || 'application/octet-stream' });
const blobURL = window.URL.createObjectURL(blob);
const tempLink = document.createElement('a');
tempLink.style.display = 'none';
tempLink.href = blobURL;
tempLink.setAttribute('download', filename);
if (typeof tempLink.download === 'undefined') {
tempLink.setAttribute('target', '_blank');
}
document.body.appendChild(tempLink);
tempLink.click();
document.body.removeChild(tempLink);
window.URL.revokeObjectURL(blobURL);
}
还可以通过 header中的content-disposition获取 fileName,成为文件的下载名称
可能会存在乱码问题,可以使用 decodeURIComponent 解决;
//从header中读取文件名称
const headerFilename = result.headers['content-disposition']?.split(';')[1].split('=')[1];
const fileName = decodeURIComponent(headerFilename);
downloadByData(result.data, fileName, 'application/json');
可能会在header中无法获取到 content-disposition ;
① 拦截时,只返回了部分数据,
// 添加响应拦截器 axios.interceptors.response.use(response=>{ // 对响应数据做点什么 return response.data; //这里只把这个响应里的data返回回来了,所以取不到headers,想要全部信息就return response; }, error=>{ // 对响应错误做点什么 return Promise.reject(error); });
②后台没有返回 content-disposition 参数,需要后台搞一下;
查看了 network ,响应头确实有返回 content-disposition;但是打印以及通过.headers['content-disposition']就是获取不到;
是因为cros跨域,浏览器只会返回默认头部的header,并不能完全获取后端自定义的所有数据;
因此,需要后端在header中添加 Access-Control-Expose-Headers 信息;
响应首部 Access-Control-Expose-Headers 就是控制“暴露”的开关,它列出了哪些首部可以作为响应的一部分暴露给外部
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition")
这个时候就能在前端获取到响应的数据了