在 Axios 响应拦截器中反应显示弹出窗口

React Showing popup in Axios response Interceptors

我正在 React 中使用刷新令牌和 JWT 令牌身份验证。我的用例是, 如果 JWT 令牌已过期,请调用刷新令牌并再次使用 API。但是,如果刷新令牌也已过期,我想向用户显示一个警报弹出窗口(会话已过期。重新登录),然后转到登录页面。这是我的代码。我能够路由到登录页面,但我不知道如何在路由之前触发警报弹出窗口。

API.interceptors.request.use(
  (config) => {
    config.headers["Authorization"] = getToken() || "";
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);



const refreshTokenAPI = async () => {
  return await API.post("/refresh-token", {
    token: getRefreshToken("refresh_token"),
  });
};


export const doRefreshToken = async (err, API) => {
  // const history = useHistory()
  const originalConfig = err.config;

  if (err.response) {
    // Access Token was expired
    if (err.response.status === 401 && !originalConfig._retry) {
      originalConfig._retry = true;
      try {
        const rs = await refreshTokenAPI();
          const { token, refreshToken } = rs.data;
          setToken(token);
          setRefreshToken(refreshToken);
          return API(originalConfig);
      } catch (_error) {
        removeLocalStorageData(); // Removes all the token from local storage. If token is not in Local storage, the route will redirect to Sign in Page
        window.location.reload()
        return Promise.reject(_error);
      }
    }

    if (err.response.status === 403 && err.response.data && originalConfig.url === '/refresh-token') {
      removeLocalStorageData(); // Removes all the token from local storage. If token is not in Local storage, the route will redirect to Sign in Page
      window.location.reload()
    }

    if (err.response.status === 403 && err.response.data) {
      return Promise.reject(err.response.data);
    }
    
  }
}
API.interceptors.response.use(
  (res) => {
    return res;
  },
  async (err) => {
    if (err.response.status == 401 || err.response.status == 403)   {
      return await doRefreshToken(err, API);
      
    } else {
      return Promise.reject(err);
    }
    
  }
);

export default API;

removeLocalStorageData存储功能将从本地存储中清除所有令牌和数据。我不想显示 window.alert 函数来显示弹出窗口。在路由到登录页面之前,还有其他方法可以显示弹出窗口吗?

我想弹出组件。我无法在拦截器中发送状态。我正在使用任何 redux。使用我自己的自定义上下文提供程序。

为了替代window.alert,您可以使用像sweet alert2 or react-toastify这样的通知组件,它可以在反应组件之外调用。

对于 react-toastify,您需要在应用程序的根级别添加 <ToastContainer /> 组件。

import axios from "axios";
import Swal from "sweetalert2";

const api = axios.create({
  baseURL: "https://reqres.in/api"
});

api.interceptors.response.use(
  (res) => {
    return res;
  },
  async (err) => {
    if (err.response.status == 401 || err.response.status == 400) {
      Swal.fire("Can you see me?");
    }

    return Promise.reject(err);
  }
);

export default api;