当前位置: 首页 > 知识库问答 >
问题:

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

柏阳炎
2023-03-14

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

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

我似乎在使用async await时做错了什么(我认为),因为拦截在返回数据之前没有等待fetch调用(原始fetch上的statuscode似乎是401,而不是在我们获得cookie后应该是200。我也试图在拦截器内部返回fetch的响应,但返回的是未定义的)。

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

下面是我的代码

(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();
    };
    null

共有1个答案

徐俊人
2023-03-14

您可以简单地对令牌使用OriginalFetch并等待响应,如果响应是401,则只需返回空响应,以第一个fetch调用,否则更新了令牌,然后让它进入下一个条件,该条件将重新运行旧请求。

let TEMP_API = {
  '401': {
    url: 'https://run.mocky.io/v3/7a98985c-1e59-4bfb-87dd-117307b6196c',
    args: {}
  },
  '200': {
    url: 'https://jsonplaceholder.typicode.com/todos/2',
    args: {}
  },
  '404': {
    url: 'https://jsonplaceholder.typicode.com/todos/1',
    args: {
      method: "POST",
      credentials: "include"
    }
  }
}

const originalFetch = fetch;
fetch = function() {
  let self = this;
  let args = arguments;
  return originalFetch.apply(self, args).then(async function(data) {
    if (data.status === 200) console.log("---------Status 200----------");
    if (data.status === 401) {
      // request for token with original fetch if status is 401
      console.log('failed');
      let response = await originalFetch(TEMP_API['200'].url, TEMP_API['200'].args);
      // if status is 401 from token api return empty response to close recursion
      console.log("==========401 UnAuthorize.=============");
      console.log(response);
      if (response.status === 401) {
        return {};
      }
      // else set token
      // recall old fetch
      // here i used 200 because 401 or 404 old response will cause it to rerun
      // return fetch(...args); <- change to this for real scenarios
      // return fetch(args[0], args[1]); <- or to this for real sceaerios
      return fetch(TEMP_API['200'].url, TEMP_API['200'].args);
    }
    // condition will be tested again after 401 condition and will be ran with old args
    if (data.status === 404) {
      console.log("==========404 Not Found.=============");
      // here i used 200 because 401 or 404 old response will cause it to rerun
      // return fetch(...args); <- change to this for real scenarios
      // return fetch(args[0], args[1]); <- or to this for real scenarios
      return fetch(TEMP_API['200'].url, TEMP_API['200'].args);
sceaerios
    } else {
      return data;
    }
  });
};

(async function() {
  console.log("==========Example1=============");
  let example1 = await fetch(TEMP_API['404'].url, TEMP_API['404'].args);
  console.log(example1);
  console.log("==========Example2=============");
  let example2 = await fetch(TEMP_API['200'].url, TEMP_API['200'].args);
  console.log(example2);
  console.log("==========Example3=============");
  let example3 = await fetch(TEMP_API['401'].url, TEMP_API['401'].args);
  console.log(example3);
})();
 类似资料:
  • 问题内容: 我有以下动作映射 我可以使用Interceptor中的以下行获取参数映射 就像上面一样, 有什么方法可以获取 以下映射中定义的 拦截器参数 。 动作参数按以下方式定义,动作参数和拦截器参数应分别可访问。 请注意,我不想在拦截器中将参数字段声明为 在Dev Blanked的攻击之后,我实现了他的技术。它没有用,所以我在这里共享我的代码。我正在使用Struts 2.3.1.2。 图书馆 a

  • 问题内容: 我有带有不同(HTML和JSON)结果类型的Struts2操作。他们使用通用拦截器。 如果需要拦截请求,如何根据给定的操作结果类型返回结果? 例如,我转发到JSP页面。如果操作是JSON类型,我想转发JSON错误。 问题答案: 我有带有不同(HTML和JSON)结果类型的Struts2操作。他们使用通用拦截器。如果需要拦截请求,如何根据给定的动作结果类型返回结果? 例如,我的Actio

  • 我有一个带有SOAPendpoint的Spring引导应用程序和一个实现的拦截器类。问题是,此接口中没有可以访问和的覆盖方法。 我的问题是: > 每当API请求使用SOAP拦截器时,我如何获取HttpServletRequest和HttpServletResponse对象(我看到了许多使用WebMVCConfigureAdapter和HandlerInterceptor的示例,但它只对Rest@C

  • 我有一个使用express api的react应用程序。我正在尝试在访问令牌过期时刷新令牌。我正在使用axios拦截器来实现这一成就。 它卡在某个地方了。我使用console.log来调试它。从控制台; 发布http://localhost:5000/api/auth/token?null 401(未经授权) 之后什么都没发生。我该怎么办?谢谢你的帮助

  • 问题内容: 我真的很感谢Spring 3阳极驱动的Web控制器映射 我有很多带有类似签名的控制器: 但是我的问题是,我想编写一个拦截器,该拦截器在处理后会通过BindingResults-如何从HttpRequest或HttpResponse中获取它们? 因为intercpetor方法具有相同的签名 问题答案: 因此,在@Axtavt的大力帮助下,我得出了结论,即可以在postHandle方法中从

  • 问题内容: 如何在Hibernate拦截器中获取Hibernate会话? 我正在尝试使用Hibernate通过组织ID透明地强制执行数据访问。我设置了一个全局筛选器,以按组织ID筛选所有查询。现在,在保存/更新之前,我需要使用实体拦截器在所有实体上设置组织ID。 组织ID来自HttpSession 我已经在Hibernate会话中将Organizational Id设置为Filter属性,我想在我