如何让 axios 拦截器重试原始请求?

Posted

技术标签:

【中文标题】如何让 axios 拦截器重试原始请求?【英文标题】:How can I get an axios interceptor to retry the original request? 【发布时间】:2020-02-12 04:30:51 【问题描述】:

我正在尝试在我的 vue.js 应用程序中实现令牌刷新。到目前为止,这是有效的,因为它会在 401 响应时刷新商店中的令牌,但我需要做的就是让拦截器在之后再次重试原始请求。

ma​​in.js

axios.interceptors.response.use(
    response => 
        return response;
    ,
    error => 
        console.log("original request", error.config);
        if (error.response.status === 401 && error.response.statusText === "Unauthorized") 
            store.dispatch("authRefresh")
                .then(res => 
                    //retry original request???
                )
                .catch(err => 
                    //take user to login page
                    this.router.push("/");
                );
        
    
);

store.js

authRefresh(context) 
    return new Promise((resolve, reject) => 
        axios.get("auth/refresh", context.getters.getHeaders)
            .then(response => 
                //set new token in state and storage
                context.commit("addNewToken", response.data.data);
                resolve(response);
            )
            .catch(error => 
                reject(error);
            );
    );
,

我可以在控制台中记录error.config 并查看原始请求,但是有人知道我从这里做什么来重试原始请求吗?如果失败,也可以阻止它一遍又一遍地循环。

还是我这样做完全错了?欢迎提出建设性的批评。

【问题讨论】:

【参考方案1】:

你可以这样做:

axios.interceptors.response.use(function (response) 
  return response;
, function (error) 

  const originalRequest = error.config;

  if (error.response.status === 401 && !originalRequest._retry) 

    originalRequest._retry = true;

    const refreshToken = window.localStorage.getItem('refreshToken');
    return axios.post('http://localhost:8000/auth/refresh',  refreshToken )
      .then((data) => 
        window.localStorage.setItem('token', data.token);
        window.localStorage.setItem('refreshToken', data.refreshToken);
        axios.defaults.headers.common['Authorization'] = 'Bearer ' + data.token;
        originalRequest.headers['Authorization'] = 'Bearer ' + data.token;
        return axios(originalRequest);
      );
  

  return Promise.reject(error);
);

【讨论】:

当有多个请求同时运行时这个可以工作吗? 抱歉,对多个请求一无所知

以上是关于如何让 axios 拦截器重试原始请求?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 React Router V4 从 axios 拦截器重定向?

使用多个请求刷新访问令牌

Axios 中的单元测试拦截器逻辑

尝试在http拦截器中捕获401,刷新我的会话并重试原始请求

Axios使用拦截器全局处理请求重试

vue中axios 配置请求拦截功能 及请求方式如何封装