【问题标题】:How to add interceptor function to Axios?如何在axios中添加拦截器功能?
【发布时间】:2020-03-04 00:14:05
【问题描述】:

好的,所以我想在我的全局 axios 配置中添加一个响应拦截器,如果在刷新 401 错误后重试请求一次令牌。

这是我当前的全局 axios 配置:

import axios from "axios";

export default axios.create({
  baseURL: process.env.REACT_APP_API,
  headers: {
    "content-type": "application/json"
  },
  responseType: "json"
});

现在我已经研究了我的问题已解决 here,但是,我不知道如何在我的 axios 配置文件的答案中附加或使用拦截器功能(在我将它编辑到我的需要 ofc) 拦截器函数如下所示:

createAxiosResponseInterceptor() {
    const interceptor = axios.interceptors.response.use(
        response => response,
        error => {
            // Reject promise if usual error
            if (errorResponse.status !== 401) {
                return Promise.reject(error);
            }

            /* 
             * When response code is 401, try to refresh the token.
             * Eject the interceptor so it doesn't loop in case
             * token refresh causes the 401 response
             */
            axios.interceptors.response.eject(interceptor);

            return axios.post('/api/refresh_token', {
                'refresh_token': this._getToken('refresh_token')
            }).then(response => {
                saveToken();
                error.response.config.headers['Authorization'] = 'Bearer ' + response.data.access_token;
                return axios(error.response.config);
            }).catch(error => {
                destroyToken();
                this.router.push('/login');
                return Promise.reject(error);
            }).finally(createAxiosResponseInterceptor);
        }
    );
}

非常感谢!

【问题讨论】:

    标签: javascript reactjs axios


    【解决方案1】:

    如果我正确理解了这个问题,您需要在您的自定义公理实例上调用拦截器创建函数。所以像:

    import axios from "axios";
    
    const instance = axios.create({
      baseURL: process.env.REACT_APP_API,
      headers: {
        "content-type": "application/json"
      },
      responseType: "json"
    });
    
    function createAxiosResponseInterceptor(axiosInstance) {
        const interceptor = axiosInstance.interceptors.response.use(
            response => response,
            error => {
                // Reject promise if usual error
                if (errorResponse.status !== 401) {
                    return Promise.reject(error);
                }
    
                /*
                 * When response code is 401, try to refresh the token.
                 * Eject the interceptor so it doesn't loop in case
                 * token refresh causes the 401 response
                 */
                axiosInstance.interceptors.response.eject(interceptor);
    
                return axiosInstance.post('/api/refresh_token', {
                    'refresh_token': this._getToken('refresh_token')
                }).then(response => {
                    saveToken();
                    error.response.config.headers['Authorization'] = 'Bearer ' + response.data.access_token;
                    return axiosInstance(error.response.config);
                }).catch(error => {
                    destroyToken();
                    this.router.push('/login');
                    return Promise.reject(error);
                }).finally(createAxiosResponseInterceptor);
            }
        );
    }
    
    createAxiosResponseInterceptor(instance);
    
    export default instance;
    

    并使createAxiosResponseInterceptor函数以axios实例为参数。

    【讨论】:

    • 好吧,这听起来不错,但我应该把函数放在哪里开始呢?其他地方并导入?
    • 我想这应该不重要。如果您在其他任何地方都不需要它(可能不需要),我会把它放在同一个模块中......
    • 函数的位置好像还是不对,有什么线索吗? prntscr.com/ptqim8
    【解决方案2】:

    我认为您需要使用 axios 的自定义实例调用您的拦截创建者。 你可以这样做

    const instance = axios.create({
     baseURL: process.env.REACT_APP_API,
     headers: {
     "content-type": "application/json"
     },
     responseType: "json"
    });
    

    并将此实例传递给 createAxiosResponseInterceptor

    createAxiosResponseInterceptor(instance);
    

    您必须更改您的 createAxiosResponseInterceptor 才能接收此实例

    function createAxiosResponseInterceptor(instance) {
    const interceptor = instance.interceptors.response.use(
        response => response,
        error => {
            // Reject promise if usual error
            if (errorResponse.status !== 401) {
                return Promise.reject(error);
            }
    
            /* 
             * When response code is 401, try to refresh the token.
             * Eject the interceptor so it doesn't loop in case
             * token refresh causes the 401 response
             */
            instance.interceptors.response.eject(interceptor);
    
            return instance.post('/api/refresh_token', {
                'refresh_token': this._getToken('refresh_token')
            }).then(response => {
                saveToken();
                error.response.config.headers['Authorization'] = 'Bearer ' + response.data.access_token;
                return instance(error.response.config);
            }).catch(error => {
                destroyToken();
                this.router.push('/login');
                return Promise.reject(error);
            }).finally(createAxiosResponseInterceptor);
        }
    );
    }
    

    当然还有导出为

    export default instance;
    

    希望对你有帮助

    【讨论】:

    • 很有帮助,不过好像函数的位置还是不合适,有什么线索吗? prntscr.com/ptqim8
    • 你需要使用function关键字
    猜你喜欢
    • 2023-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-20
    • 2020-09-16
    • 1970-01-01
    • 2018-11-06
    相关资源
    最近更新 更多