目录
1.下载方法封装
2.将后端返回的文件流转换为文件
3.总结
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) // 创建URLlet link = document.createElement("a");link.href = objectUrllink.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 --savepnpm 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方式,比较方便