我正在尝试创建一个拦截器,用于在JavaScript中获取(更具体地说是React)。它应该从每次调用的获取中获取结果,如果是401错误,它应该向另一个路由发起新的获取调用以获取cookie(刷新令牌)。然后,应该再次尝试原始的fetch调用(因为现在用户已经登录)。
我已经成功地触发了新的fetch调用,并为每个调用发回了cookie,但我遇到了以下两个问题:
1.我现在不知道如何在收到刷新令牌后重试fetch调用。这可能吗?我发现了fetch-retry npm(https://www.npmjs.com/package/fetch-retry),但不确定如何以及是否可以在拦截器上实现它,因为它应该为原始的fetch调用完成。
1.我似乎在async await上做错了什么(我认为),因为拦截在返回数据之前没有等待fetch调用(原始fetch的状态码似乎是401而不是200,在我们获得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
});
};
})();
字符串
编辑:为了更清楚地说明我在做什么。我需要一个如上所述的拦截器来工作,这样我就不必在每次fetch调用后都做这样的事情:
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();
};
型
所以基本上拦截器应该:
1.检查是否有401,如果有,则:
1.获取API/令牌
1.如果API/token返回401,它应该只返回401。
1.如果API/token返回200,它应该再次运行original fetch
4条答案
按热度按时间d5vmydt91#
你可以简单地使用
originalFetch
作为token并等待响应,如果响应是401,那么你只需返回空响应到第一个fetch调用,否则你更新了token,然后让它进入下一个条件,这将重新运行旧的请求。字符串
4smxwvx52#
尝试返回fetch promise,而不是等待它。
字符串
ru9i0ody3#
Interceptor library用于本机获取命令。它修补了全局获取方法,并允许您在浏览器,节点和Webworker环境中使用。
fetch-retry它封装了任何Fetch API包(例如:同构获取、交叉获取、同构取消获取等),并重试由于网络问题而失败的请求。它还可以配置为重试特定HTTP状态代码的请求。
wh6knrhe4#
下面是一个使用
return-fetch
library在响应状态为401时重试的示例:https://stackblitz.com/edit/return-fetch-example-retrying?file=index.ts的字符串
如果你想用自己的
fetch
替换全局fetch
,只需保存全局fetch引用并替换它。型