reactjs - 如何在另一个请求完成之前防止用 Axios 发起请求?
我正在开发一个大型的网络应用程序,它会从不同的地方向服务器发出多个请求。我们使用的令牌有效期为15分钟。这意味着当令牌过期时,会使用刷新令牌来生成一个新的令牌和一个新的刷新令牌。我们正在使用 axios 的拦截器来检测令牌是否已过期。基于此,我们会执行一个请求来生成一个新的令牌。
现在的问题是,在我们发出请求以获取新令牌的期间,所有的 API 调用都会失败!
所以我现在的问题是,是否有可能在某个特定调用完全执行之前阻止发送请求(使用 axios)?
export const runRefreshToken = (errorCallback: () => void): void => {
Axios.interceptors.response.use(
(response: AxiosResponse<any>): AxiosResponse<any> => {
return response;
}, (error: any): any => {
const original = error.config;
const loginVerification = !(original.url as string).startsWith("api/login");
if (error.response && error.response.status === 401 && error.config && loginVerification && !error.config.__retry) {
return new Promise((resolve): void => {
original.__retry = true;
const response = fetch("api/login/refresh-token", { method: 'POST' })
.then((): AxiosPromise<any> => {
return Axios(original);
})
.catch((): void => errorCallback())
resolve(response);
});
} else if (error.config.__retry && original.url !== "api/login/verify-authentication") {
history.push("/login");
}
return Promise.reject(error);
}
);
}
提前感谢
答案#1
这是我在几个团队中遇到过的问题。我们使用的解决方案是在应用的顶层有一个组件,它会发起初始请求,并且在成功之前不会渲染任何子组件。
import React from 'react';
import { useAuthUser } from './hooks';
export const AuthenticateUser = ({ children }) => {
const { hasError, isLoading, shouldRedirectToLoginPage, handleRedirectToLoginPage } = useAuthUser();
if (isLoading) {
return <LoadingPage>;
}
if (hasError) {
return <ErrorPage>;
}
return children;
};
钩子文件看起来像
import { userSlice } from 'state/user';
import { useAppDispatch } from 'state/hooks';
import { useEffect } from 'react';
import { useUserDetails } from 'api/userRequests';
export function useUserDetailsProps(): UserDetailsProps {
const { data, isLoading, error } = useUserDetails();
const dispatch = useAppDispatch();
useEffect(() => {
if (data != null) {
dispatch(userSlice.actions.authenticatedUserReceived(data));
}
}, [data, dispatch]);
return {
hasError: !!error,
isLoading,
shouldRedirectToLoginPage: !!error && error.response?.status === 401,
handleRedirectToLoginPage,
};
}
