前端设置请求的responseType为'blob'
指定响应的数据类型为二进制数据流,请求成功会返回文件流内容。
axios.get(url, { responseType: 'blob' })
转为blob对象
使用new Blob()将请求返回的文件流转为blob对象。
axios
.get(url, { responseType: 'blob' })
.then(res => {
const blob = new Blob([res.data]);
})
将blob对象转成URL进行显示或下载
使用URL.createObjectURL()将blob对象转为URL。
axios
.get(url, { responseType: 'blob' })
.then(res => {
const blob = new Blob([res.data]);
const url = URL.createObjectURL(blob);
})
请求文件流并下载
/**
* @param url 接口请求地址
* @param fileName 下载的文件名称
* @returns Promise
*/
export const downloadFile = async(url: string, fileName: string) => {
return axios
.get(url, { responseType: 'blob' })
.then(res => {
const blob = new Blob([res.data]);
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName;
link.click();
// 释放一个之前已经存在的、通过调用URL.createObjectURL()创建的URL对象
URL.revokeObjectURL(url);
message.success("下载成功");
return res;
})
.catch((error) => {
message.error("下载失败");
return Promise.reject(error);
})
}
请求文件流失败时的处理
请求的responseType设置为'blob'时,请求成功会返回文件流内容。但是请求失败的时候后端返回的是json,这种情况在我们通常封装的axios中判断后端返回的code值就不适用了,需要进行特殊处理。
- 将responseType设置为'json',请求成功之后将json格式转化成blob在进行导出。
- 将responseType设置为'blob',请求失败之后将blob格式转化成json格式再进行错误提示。(采用的形式)
/**
* @param url 接口请求地址
* @param fileName 下载的文件名称
* @returns Promise
*/
export const downloadFile = async(url: string, fileName: string) => {
return axios
.get(url, { responseType: 'blob' })
.then(res => {
// 请求失败之后的处理 (请求失败时的content-type为application/json)
if (res.headers['content-type'] === 'application/json') {
// 将blob转为json进行解析
const reader = new FileReader();
reader.readAsText(res.data, 'utf-8');
reader.onload = function() {
const parseObj = JSON.parse(reader.result);
message.error(parseObj.msg || '导出失败');
}
return Promise.reject('导出失败');
}
const blob = new Blob([res.data]);
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName;
link.click();
// 释放一个之前已经存在的、通过调用URL.createObjectURL()创建的URL对象
URL.revokeObjectURL(url);
message.success("下载成功");
return res;
})
.catch((error) => {
message.error("下载失败");
return Promise.reject(error);
})
}