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

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 请求响应拦截器简单实现 中间件)