如何向Axios添加拦截器函数?

3

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

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

import axios from "axios";

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

现在我已经对我的问题进行了研究,并且得到了解决,解决方案可以在这里找到。但是,我不知道如何将那里的拦截器函数添加或使用到我的axios配置文件中(在根据我的需求进行编辑后)。拦截器函数看起来像这样:

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);
        }
    );
}

非常感谢!
2个回答

3

如果我正确理解问题,您需要在自定义的公理实例上调用拦截器创建函数。因此,类似以下内容:

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 实例作为参数。


好的,这听起来不错,但是我应该从哪里放置该函数呢?放在其他地方然后导入? - Omar Hussein
我猜这并不重要。如果你不需要在其他地方使用它(很可能不需要),我会把它放在同一个模块中... - kidney
似乎函数的放置位置仍然不恰当,有任何线索吗?prntscr.com/ptqim8 - Omar Hussein

1

我认为您需要使用自定义的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;

希望它能有所帮助。

非常有帮助,但似乎函数的放置仍不正确,有什么线索吗? - Omar Hussein
你需要使用函数关键字。 - ibtsam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接