前端封装通用下载方法及下载后端返回的文件流

目录

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) // 创建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方式,比较方便

相关推荐
Boilermaker19922 分钟前
【Java EE】SpringIoC
前端·数据库·spring
中微子13 分钟前
JavaScript 防抖与节流:从原理到实践的完整指南
前端·javascript
天天向上102428 分钟前
Vue 配置打包后可编辑的变量
前端·javascript·vue.js
芬兰y44 分钟前
VUE 带有搜索功能的穿梭框(简单demo)
前端·javascript·vue.js
好果不榨汁1 小时前
qiankun 路由选择不同模式如何书写不同的配置
前端·vue.js
小蜜蜂dry1 小时前
Fetch 笔记
前端·javascript
拾光拾趣录1 小时前
列表分页中的快速翻页竞态问题
前端·javascript
小old弟1 小时前
vue3,你看setup设计详解,也是个人才
前端
Lefan1 小时前
一文了解什么是Dart
前端·flutter·dart
Patrick_Wilson1 小时前
青苔漫染待客迟
前端·设计模式·架构