获取和获取重试的拦截器?(Javascript)

获取和获取重试的拦截器?(Javascript),javascript,interceptor,Javascript,Interceptor,我正在尝试创建一个用于获取javascript的拦截器(更具体地说,请做出反应)。它应该从调用的每个fetch中获取结果,如果是401错误,它应该启动对另一个路由的新fetch调用以获取cookie(刷新令牌)。然后,应该再次尝试原始的fetch调用(因为现在用户已登录) 我已成功触发新的fetch调用,并为每个调用发回cookie,但我遇到以下两个问题: 我现在不知道如何在收到刷新令牌后重试获取调用。可能吗?我找到了fetch retry npm(),但不确定如何以及是否可以在拦截器上实现它,

我正在尝试创建一个用于获取javascript的拦截器(更具体地说,请做出反应)。它应该从调用的每个fetch中获取结果,如果是401错误,它应该启动对另一个路由的新fetch调用以获取cookie(刷新令牌)。然后,应该再次尝试原始的fetch调用(因为现在用户已登录)

我已成功触发新的fetch调用,并为每个调用发回cookie,但我遇到以下两个问题:

  • 我现在不知道如何在收到刷新令牌后重试获取调用。可能吗?我找到了fetch retry npm(),但不确定如何以及是否可以在拦截器上实现它,何时应该为原始的fetch调用实现它

  • 我认为async await似乎有问题,因为截获在返回数据之前没有等待fetch调用(原始获取上的状态码似乎是401,而不是200,在我们获得cookie之后应该是200。我还试图在拦截器内返回获取的响应,但返回的是未定义的)

  • 你知道怎么解决这个问题吗?有人做过类似的事情吗

    下面是我的代码:

    (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/令牌
  • 如果api/令牌返回401,它应该只返回401
  • 如果api/令牌返回200,它应该再次运行原始获取

  • 尝试重新调整获取承诺,而不是等待

    (函数(){
    const originalFetch=fetch;
    fetch=函数(){
    返回originalFetch.apply(这个,参数)。然后(函数(数据){
    if(data.status==200)console.log(“------状态200------”;
    如果(data.status==404){
    console.log(“===================404未找到)。=========================”;
    回传(`https://jsonplaceholder.typicode.com/todos/2`);
    }否则{
    返回数据;
    }
    });
    };
    })();
    功能测试(id){
    //将触发404状态
    回传(`https://jsonplaceholder.typicode.com/todos/`+id{
    方法:“张贴”,
    证书:“包括”,
    });
    }
    
    测试(1)。然后((i)=>console.log(i));
    您可以简单地对令牌使用
    originalFetch
    并等待响应。如果响应为401,则您只需返回空响应以进行第一次提取调用,否则您将更新令牌,然后让它进入下一个条件,该条件将重新运行旧请求

    let TEMP_API={
    '401': {
    网址:'https://run.mocky.io/v3/7a98985c-1e59-4bfb-87dd-117307b6196c',
    args:{}
    },
    '200': {
    网址:'https://jsonplaceholder.typicode.com/todos/2',
    args:{}
    },
    '404': {
    网址:'https://jsonplaceholder.typicode.com/todos/1',
    args:{
    方法:“张贴”,
    凭据:“包括”
    }
    }
    }
    const originalFetch=fetch;
    fetch=函数(){
    让自我=这个;
    设args=参数;
    返回originalFetch.apply(self,args).then(异步函数(数据){
    if(data.status==200)console.log(“------状态200------”;
    如果(data.status==401){
    //如果状态为401,则请求具有原始提取的令牌
    console.log('failed');
    let response=await originalFetch(临时API['200'].url,临时API['200'].args);
    //如果令牌api的状态为401,则返回空响应以关闭递归
    console.log(“===================401未经授权)。=========================”;
    控制台日志(响应);
    如果(response.status==401){
    返回{};
    }
    //其他设置令牌
    //回忆往事
    //这里我使用了200,因为401或404旧响应将导致它重新运行
    
    //返回获取(…参数);谢谢!这返回了正确的状态并解决了我的第二个问题。但是我无法解决问题1,有什么想法吗?嗨,谢谢你花时间尝试解决这个问题!我猜你的意思是我先检查刷新令牌?刷新令牌命中数据库以检查验证,所以我不希望它命中数据库这就是为什么我只在访问令牌为false时才需要它检查刷新令牌(返回401)@HejHej123令牌请求仅在响应状态为
    401
    时运行,如果响应状态不是401,则它将永远不会运行,如果令牌api返回
    401
    ,则您将返回取消下一次获取重试对不起,我只是在代码之前阅读了您的注释,我误解了。但是否可以让它重新运行没有指定url的原始fetch?我只希望在每次fetch调用上运行它,而不对原始文件进行任何修改fetchcode@Hejhejhej123我已经用临时未经授权的api和解释更新了我的答案。非常感谢!就像我想要的那样工作。但是我没有得到404。什么时候用的?我没有从所以我只使用了return并删除了if(data.status==404)。