目录
1.下载方法封装
①说明
前端的请求大概分为三种类型
普通请求:常用的get,post,put,delete等请求
上传请求:使用post请求,发送formdata对象的参数,formdata中存放文件及其他参数
下载请求:使用post请求,设置响应格式为blob或者arraybuffer
②通用下载请求说明
api:
// 共通下载方法
export function dowload(url:string,params:any,filename:string,config:any) {
return axios.post(url,params,{ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
responseType: 'blob',
...config})
.then((data:any) =>{
if(data.type !== 'application/json'){
const blob = new Blob([data],{ type: 'application/vnd.ms-excel' })
saveAs(blob,filename)
// let objectUrl = URL.createObjectURL(blob) // 创建URL
// let link = document.createElement("a");
// link.href = objectUrl
// link.download =filename // 自定义文件名
// link.click() // 下载文件
// URL.revokeObjectURL(objectUrl); // 释放内存
}
}).catch((r:any) =>{
console.log(r)
Message.error({ content: '下载文件出现错误,请联系管理员!', position: 'top' });
})
}
说明:
前端下载后端的文件,一般分为两种类型,后端返回文件流或者后端将文件存储在服务器,将地址返回至前端。
我使用的是后端返回文件流的方式,前端的请求需要将responseType设置为blob格式,代表后端返回的是二进制文件流。content-type按照需要进行设置,可以设置为application/x-www-form-urlencoded或者application/json,不同的方式决定了后端接收参数的方式不一样。
拦截器设置:
axios.interceptors.response.use(
(response: AxiosResponse<any>) => {
// 二进制数据则直接返回
if (response.request.responseType === 'blob') {
return response.data
}
const res = response.data;
let resCode = res.resHdr?.resCode;
let resMsg = res.resHdr?.resMsg || "请求未知异常";
if (resCode == "9990_10" || resCode == "9990_9") {
Message.error({
content: "登录信息过期,请重新登录",
duration: 5 * 1000,
});
// 跳转登录页面
router.push("/login");
return Promise.reject(new Error(resMsg));
}
if (resCode !== "0000") {
Message.error({
content: resMsg,
duration: 5 * 1000,
});
return Promise.reject(new Error(resMsg));
}
return res.resBody;
},
(error) => {
Message.error({
content: error.msg || "请求未知异常",
duration: 5 * 1000,
});
return Promise.reject(error);
}
);
说明:
响应拦截器中要对responseType进行判断,如果是blob格式的,直接返回response中的data,其他格式时,一般为json,需要获取返回的data的返回值进行判断,登录过期时跳转到登录画面,并进行信息提示,异常时进行信息提示,正常时返回data,然后在接口中对data的内容进行处理。
2.将后端返回的文件流转换为文件
在通过下载方法中,获取到返回的data数据,需要将数据流转为文件。
方式1:
// 共通下载方法
export function dowload(url:string,params:any,filename:string,config:any) {
return axios.post(url,params,{ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
responseType: 'blob',
...config})
.then((data:any) =>{
if(data.type !== 'application/json'){
const blob = new Blob([data],{ type: 'application/vnd.ms-excel' })
let objectUrl = URL.createObjectURL(blob) // 创建URL
let link = document.createElement("a");
link.href = objectUrl
link.download =filename // 自定义文件名
link.click() // 下载文件
URL.revokeObjectURL(objectUrl); // 释放内存
}
}).catch((r:any) =>{
console.log(r)
Message.error({ content: '下载文件出现错误,请联系管理员!', position: 'top' });
})
}
将data转换为blob对象,然后根据blob创建url,再创建一个a元素,将a元素的href属性和url进行绑定,再设置下载的文件名,触发click事件进行下载。
方式2:
使用file-saver方式
①安装依赖:
pnpm install file-saver --save
pnpm install @types/file-saver --save-dev
②使用
import { saveAs } from 'file-saver'
// 共通下载方法
export function dowload(url:string,params:any,filename:string,config:any) {
return axios.post(url,params,{ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
responseType: 'blob',
...config})
.then((data:any) =>{
if(data.type !== 'application/json'){
const blob = new Blob([data],{ type: 'application/vnd.ms-excel' })
saveAs(blob,filename)
}
}).catch((r:any) =>{
console.log(r)
Message.error({ content: '下载文件出现错误,请联系管理员!', position: 'top' });
})
}
调用saveAs方式,传递blob对象及文件名即可
3.总结
注意通过下载方法的封装
注意响应拦截器首先要对响应类型进行判断,blob格式直接返回data
生成文件直接使用file-saver方式,比较方便