开发者问题收集

React + axios 拦截器:在组件上下文中重试原始请求

2023-02-09
533

我正在学习 React,并使用 axios 和 JWT 进行身份验证。我编写了一个拦截器来自动刷新令牌:

privateAxios.interceptors.response.use(
  (response) => {
    return response;
  },
  (error) => {
    const { config, response } = error;
    const originalRequest = config;
    if (response?.status === 401) {
      apiProvider
        .refreshToken()
        .then(() => {
          let headers = getAuthHeaders();
          privateAxios.defaults.headers = headers;
          originalRequest.headers = headers;
          return privateAxios(originalRequest);
        })
        .catch((err) => {
          logout();
          return Promise.reject(err);
        });
    }
    return Promise.reject(error);
  }
);

在我的组件上,我有以下内容:

api.post(data)
  .then(() => {
    showSuccessFeedbackForm();
    reloadTable();
    handleClose();
  })
  .catch((error) => {
    setAlertInfos({
      message: JSON.stringify(error.response.data),
      severity: "error",
    });
    setShowAlert(true);
  })
  .finally(() => {
    setIsLoaded(true);
  });

我的问题是,如果需要刷新令牌(当代码到达 return privateAxios(originalRequest) 时),我想继续组件的正常“流程”(即 showSuccessFeedbackForm()reloadTable()handleClose() )。

我该如何实现这一点?

1个回答

看起来您只需要 return apiProvider.refreshToken()... 调用。在 return privateAxios(originalRequest); 返回后,将执行 return Promise.reject(error); ,这会导致前端收到拒绝而不是解决方案。

考虑这个拦截的错误,它 不会抛出 错误给仍然“解决”的前端:

axios.interceptors.response.use(
  (res) => res,
  (err) => {
    console.log("##### AXIOS ERROR #####");
    dispatch(increment());
  }
);

只需将其更改为此,前端就会捕获错误,而这正是您的代码本质上在做的事情:

axios.interceptors.response.use(
  (res) => res,
  (err) => {
    console.log("##### AXIOS ERROR #####");
    return Promise.reject();
  }
);
Wesley LeMahieu
2023-02-09