英文:
React + axios interceptors: retry original request within component's context
问题
我正在学习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()
)。我该如何实现这一点?
英文:
I'm learning React and I'm using axios
and JWT for authentication. I have written an interceptor to refresh the token automatically:
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);
}
);
On my component I have the following:
api.post(data)
.then(() => {
showSuccessFeedbackForm();
reloadTable();
handleClose();
})
.catch((error) => {
setAlertInfos({
message: JSON.stringify(error.response.data),
severity: "error",
});
setShowAlert(true);
})
.finally(() => {
setIsLoaded(true);
});
My problem is that I want to continue with the component's normal "flow" (i.e., showSuccessFeedbackForm()
and reloadTable()
and handleClose()
) if the token needed to be refreshed (when the code reaches return privateAxios(originalRequest)
).
How can I accomplish this?
答案1
得分: 2
只需要将 apiProvider.refreshToken()
调用处的 return
修改为 return
。在 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();
}
);
英文:
It looks like you should just have to return
the apiProvider.refreshToken()...
call. After return privateAxios(originalRequest);
returns, then return Promise.reject(error);
is executing which causes the front-end to receiving an rejection not a resolution.
Consider this intercepted error which does not throw an error to the frontend which still "resolves":
axios.interceptors.response.use(
(res) => res,
(err) => {
console.log("##### AXIOS ERROR #####");
dispatch(increment());
}
);
Simply changing it to this causes the front-end to catch an error which is what your code is essentially doing:
axios.interceptors.response.use(
(res) => res,
(err) => {
console.log("##### AXIOS ERROR #####");
return Promise.reject();
}
);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论