美文网首页
axios 请求响应拦截器简单实现 中间件

axios 请求响应拦截器简单实现 中间件

作者: 辉的书 | 来源:发表于2020-05-17 15:31 被阅读0次

    axios是结合promise一起使用的,其中重要的一点是使用了promise.resolve()和对应的promise.then();

    先来看一个例子:

    const axios = (config) => {
        console.log(config);
        if (config.error) {
            return Promise.reject({
                error: "error in axios"
            });
        } else {
            return Promise.resolve({
                ...config,
                result: config.result,
            });
        }
    };
    //执行axios方法
    axios({
        error: "",
        result: 'jack',
    }).then(res => {
        console.log('res= ', res);
    }).catch(err => {
        console.log('err=> ', err);
    });
    

    当执行上面的axios方法的时候,会随着传入参数的判断处理,执行对应的then里面的函数回调方法,从而达到异步数据流的控制。


    拦截器实现思路:

    我们可以通过设置一个操作链,存储请求拦截操作、响应拦截操作,通过promise的异步流达到依次顺序执行的目的。

    //自定义axios
    const axios = {
        config: {
            url: '/',
            method: 'get',
            baseURL: "",
            params: {},
        }
    };
    //存储请求、响应拦截操作函数
    axios.interceptors = {
        request: [],
        response: [],
    };
    //调用拦截器的时候,将拦截操作方法加入拦截器操作链
    axios.interceptors.request.use = (resolved, rejected) => {
        axios.interceptors.request.push({ resolved, rejected });
    };
    axios.interceptors.response.use = (resolved, rejected) => {
        axios.interceptors.response.push({ resolved, rejected });
    };
    //axios网络请求的核心操作
    axios.action = (config) => {
        return new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest();
            xhr.open(config.method, config.baseURL + config.url, true);
            xhr.onload = () => {
                // console.log(xhr.status);
                // console.log(xhr.responseText);
                resolve(xhr.responseText);
            };
            xhr.onerror = () => {
                //console.log('======== xhr.error');
                reject('xhr error 错误');
            };
            xhr.send();
        });
    };
    //axios执行,调用拦截器处理
    axios.run = (config) => {
        //console.log('config --- ', config);
        const chain = [
            {
                resolved: axios.action,
                rejected: undefined
            }
        ];
    
        axios.interceptors.request.forEach(interceptor => {
            chain.unshift(interceptor);
        });
    
        axios.interceptors.response.forEach(interceptor => {
            chain.push(interceptor);
        });
    
        let promise = Promise.resolve(config);
    
        while (chain.length) {
            const { resolved, rejected } = chain.shift();
            promise = promise.then(resolved, rejected);
        }
    
        return promise;
    };
    //get请求
    axios.get = (url) => {
        axios.config.method = 'get';
        axios.config.url = url;
        return axios.run(axios.config);
    };
    //post请求
    axios.post = (url) => {
        axios.config.method = 'post';
        axios.config.url = url;
        return axios.run(axios.config);
    };
    //导出axios
    export default axios;
    

    自定义axios的使用:

    import axios from './myAxios.js';
    
    const getBtn = document.querySelector('#get');
    const postBtn = document.querySelector('#post');
    //axios的请求配置
    axios.config.baseURL = "http://localhost:9000";
    
    //get请求
    getBtn.onclick = (e)=>{
        //console.log('eee, ', e.target);
        axios.get("/getData").then(res=>{
            console.log('get request result = ', res);
            alert(res);
        }).catch(err=>{
            alert('post err -> ', err);
        });
    };
    //post请求
    postBtn.onclick = (e)=>{
        //console.log('eee, ', e.target);
        axios.post("/postData").then(res=>{
            console.log('get request result = ', res);
            alert(res);
        }).catch(err=>{
            alert('post err -> ', err);
        });
    };
    
    //请求拦截器 中间件
    axios.interceptors.request.use((config) => {
        console.log('interceptors.request1');
        return config;
    }, (error) => {
        return Promise.reject(error);
    });
    axios.interceptors.request.use((config) => {
        console.log('interceptors.request2');
        return config;
    }, (error) => {
        return Promise.reject(error);
    });
    //响应拦截器 中间件
    axios.interceptors.response.use((res) => {
        console.log('interceptors.response1');
        return res;
    }, (error) => {
        return Promise.reject(error);
    });
    axios.interceptors.response.use((res) => {
        console.log('interceptors.response2');
        return res;
    }, (error) => {
        return Promise.reject(error);
    });
    

    使用多个请求响应拦截器的时候,要注意拦截器写入的先后顺序,当在拦截器中对config做拦截操作处理时,会有对接下来的拦截器中config的操作有影响。如上请求,拦截器的执行顺序是:

    interceptors.request2
    interceptors.request1
    ajax请求 http://localhost:9000/getData
    interceptors.response1
    interceptors.response2
    

    githubdemo

    相关文章

      网友评论

          本文标题:axios 请求响应拦截器简单实现 中间件

          本文链接:https://www.haomeiwen.com/subject/jgqsohtx.html