Axios封装拦截器

2 篇文章 0 订阅
const pendingRequest = new Map(); // 请求对象
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
var qs = require('qs');

export function dataFromServer(apiUrl, type, param, data) {
    const request = axios.create();
    //  创建一个新的axios实例对象  这样做的目的就是 不会进入之前的请求拦截和响应 防止进入死循环

    // 添加请求拦截器
    request.interceptors.request.use(
        function (config) {
            // 在发送请求之前做些什么
            // 获取请求key

            let requestKey = getReqKey(config);

            if (pendingRequest.has(requestKey)) { // 是重复请求
                //let cancel;
                //config.cancelToken = new CancelToken(function executor(c) {
                    //cancel = c;
                //})
                //cancel();
                //source.cancel('Operation canceled by the user.');
                removeReqKey(requestKey);

            } else {
                // 设置cancelToken
                config.cancelToken = new CancelToken(function executor(cancel) {
                    pendingRequest.set(requestKey, cancel); // 设置
                })
            }

            return config;

        },
        function (error) {
            // 对请求错误做些什么
            return Promise.reject(error);
        }
    );

    // 添加响应拦截器
    request.interceptors.response.use(
        function (response) {
            //let requestKey = getReqKey(response.config);
            //removeKey(requestKey);
            let requestKey = getReqKey(response.config);
            removeReqKey(requestKey);
            return response;
        },
        async function (error) {
            //删除失败响应
            if (error.response?.config) {
                let requestKey = getReqKey(error.response.config);
                removeKey(requestKey);
            }
     
            // 对响应错误做点什么
            // 对响应数据做点什么
            const status = error.response?.status;
            if (status == 400) {
                //  请求参数错误
            } 
            return Promise.reject(error);
        }
    );

    function removeReqKey(key) {
        if (pendingRequest.has(key)) {
            const cancelToken = pendingRequest.get(key);
            cancelToken(key); // 取消之前发送的请求
            pendingRequest.delete(key); // 请求对象中删除requestKey
        }
    }

    function removeKey(key) {
        if (pendingRequest.has(key)) {
            pendingRequest.delete(key); // 请求对象中删除requestKey
        }
    }

    function getReqKey(config) {
        // 请求方式、请求地址、请求参数生成的字符串来作为是否重复请求的依据
        const { method, url, params, data } = config; // 解构出来这些参数
        // GET ---> params  POST ---> data
        const requestKey = [method, url, qs.stringify(params),         
        qs.stringify(data)].join('&');
        console.log(config)
        return requestKey;
    }

    /**
     * 返回的Promise对象含有then、catch方法
     */
    return new Promise(function (resolve, reject) {
        request({
            url: apiUrl,
            method: type,
            params: param,
            data: data,
            headers: {
                'Content-Type': 'application/json',
            },
            cancelToken: source.token
        }).then(function (response) {
            resolve(response);
        }).catch(function (error) {
            let errStr;
            if (error && error.response) {
                if (parseInt(error.response.status, 10) === 401) {
                    //返回失败 做跳回登录页面操作
                    return;
                }
                errStr = error.response.data
            }
            reject(error);
        })
    })
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值