我正在尝试使用 JavaScript(更具体地说是 React)创建一个拦截器来拦截 fetch 请求。它应该获取每个发起的 fetch 的返回结果,如果是 401 错误,则应该发起一个新的 fetch 调用到另一个路由来获取 cookie(刷新令牌)。然后,应该再次尝试原始的 fetch 调用(因为现在用户已经登录)。
我已经成功触发了新的 fetch 调用并为每个请求发送回了 cookie,但我遇到了以下两个问题:
以下是我的代码:
我已经成功触发了新的 fetch 调用并为每个请求发送回了 cookie,但我遇到了以下两个问题:
- 我不知道如何在获取到刷新令牌后重试 fetch。这可行吗?我找到了 fetch-retry npm (https://www.npmjs.com/package/fetch-retry),但不确定我是否可以在拦截器中实现它。
- 我似乎在 async await 方面做错了什么(我认为),因为拦截器在返回数据之前未等待 fetch 调用(原始 fetch 的状态码似乎是 401,而不是在获取 cookie 后应该是的 200)。我还尝试在拦截器中返回 fetch 的响应,但返回值是 undefined。
以下是我的代码:
(function () {
const originalFetch = fetch;
fetch = function() {
return originalFetch.apply(this, arguments).then(function(data) {
if(data.status === 401) {
console.log('not authorized, trying to get refresh cookie..')
const fetchIt = async () => {
let response = await fetch(`/api/token`, {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json'
},
});
}
fetchIt();
}
return data
});
};
})();
编辑:为了更清晰地说明我的目的。我需要像我上面描述的拦截器工作,这样我就不必在每次获取调用后执行以下操作:
getData() {
const getDataAsync = async () => {
let response = await fetch(`/api/loadData`, { method: 'POST' });
if(response.status === 401) {
let responseT = await fetch(`/api/token`, {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json'
},
});
if(responseT.status === 401) {
return responseT.status
}
if(responseT.status === 200) {
response = await fetch(`/api/loadData`, { method: 'POST' });
}
}
let data = await response.json();
//Do things with data
};
getDataAsync();
};
拦截器的基本功能如下:
- 检查是否存在401状态码,如果是,则执行以下步骤:
- 获取api/token
- 若api/token返回401状态码,则直接返回
- 若api/token返回200状态码,则重新运行原始的fetch请求
401
时,@Hejhejhej123 才会请求令牌。如果响应状态不是401
,则它将永远不会运行。如果令牌 API 返回401
,则您需要返回以取消下一个获取重试。 - Chandan