【问题标题】:How to catch 401 error using fetch method of javascript如何使用 javascript 的 fetch 方法捕获 401 错误
【发布时间】:2018-09-28 20:32:15
【问题描述】:

我需要捕获错误 401 响应代码,以便在从令牌端点获取新令牌后重试。我正在使用 fetch 方法从 API 获取数据。

   const request: Request = new Request(url.toString(), {
        headers: this.defaultRequestHeaders,
        method: "get",
        mode: "cors"
    });

   const headers: Headers = new Headers({
        "Accept": "application/json",
        "Content-Type": "application/json"
    });

   fetch(request)
        .then(function(response)
         {
          ///Logic code
         })
        .catch(function(error)
        {
          ///if status code 401. Need help here
        });

【问题讨论】:

  • 尝试获取属性error.status
  • 如果我从文档中理解正确,如果服务器返回有效消息(其中401 是一个),则不会抛出error,因此请尝试.then(message => if( response.status === 401 ){ ... respond to the status code... })
  • 你打败了我,尽管将message 替换为response - 你也可以检查response.ok,它决定了状态是否在200-299范围内。
  • @VikrantSingh 你在说什么?成功的请求在then 中,返回401 的成功请求仍将在then 子句中。 catch 用于某些错误,但据我所知,dos 中的状态码并非如此。
  • @VikrantSingh 没有人说它会进入 catch 块catch 块用于发生实际错误时 - 就像什么都没有返回或有安全问题。 401 状态很简单,“是的,我们完成了这个请求,它告诉我们 '401'”,所以 401 是一个有效的响应并进入thenbro

标签: javascript api


【解决方案1】:

您可以查看then中回复的status

fetch(request)
  .then(function(response) {
    if (response.status === 401) {
      // do what you need to do here
    }
  })
  .catch(function(error) {});

【讨论】:

  • 如果请求不成功则进入内部。那么
  • 我可以在 fiddler 中看到它是 401。
  • @VikrantSingh 你很不清楚,批评别人,但没有提供任何有用的理由来解释原因。返回status 401 的成功请求仍将在then 处理程序中,因此我看不到问题所在。如果您非常确定,请自己提供答案,或者提供一些优质的 cmets 以至少帮助人们调试问题。
  • 如果401执行进入then并且可以检查状态,检查这个小提琴codepen.io/dariospadoni/pen/MGWQxO
【解决方案2】:

因为401 实际上是对服务器请求的有效响应,所以无论如何它都会执行您的有效响应。只有发生安全问题,或者服务器无响应或根本不可用时,才会使用catch 子句。把它想象成试图与某人交谈。即使他们说“我目前不可用”或“我没有该信息”,您的对话仍然成功。只有当安全人员闯入您并阻止您与收件人交谈时,或者如果收件人,对话中才会出现实际失败,您是否需要使用catch.

只需分离出您的错误处理代码,这样您就可以在请求成功但没有预期结果的情况下处理它,以及当实际错误被抛出时:

function catchError( error ){

    console.log( error );

}

request.then(response => {

    if( !response.ok ){

        catchError( response );

    } else {

        ... Act on a successful response here ...

    }

}).catch( catchError );

我在 cmets 中使用 @Noface 建议的 response.ok,因为它是有道理的,但如果你愿意,你可以只检查 response.status === 401

【讨论】:

  • 没用,只是代码重构,已经试过了。
  • @VikrantSingh 这不仅仅是你代码的“重构”,你一直在问同样的事情:我如何处理我的catch 中的 401 响应,答案很简单:它 不会自动进入你的捕获,因为它是一个有效的响应。所以请,请,在这种情况下您要解决的问题更清楚。
  • 我想你误会了,我只想在 .catch 块或 .then 块中捕获 401 错误代码。
  • @VikrantSingh 已经有两个答案可以解释这一点,您catch 通过检查成功请求的状态码会出现这样的错误。
【解决方案3】:

你可以试试这个

fetch(request)
  .then(function(response) {
    if (response.status === 401) {
      // do what you need to do here
    }
  })
  .catch(function(error) {
        console.log('DO WHAT YOU WANT')
});

【讨论】:

    【解决方案4】:

    您可以检查状态,如果不是 200(ok)则抛出错误

     fetch("some-url")
        .then(function(response)
         {
          if(response.status!==200)
           {
              throw new Error(response.status)
           }
         })
        .catch(function(error)
        {
          ///if status code 401...
        });
    

    【讨论】:

    • 如果HTTP响应状态为401,则catch方法的回调函数将不会被调用;相反,then 方法的回调函数将被调用,response.status === 401
    • 我不完全同意http请求成功时抛出错误。 401 甚至不是服务器错误,只是未经授权。最好检查响应代码并分叉您的逻辑恕我直言。
    • 在很多情况下,除了200之外还可以,主要是201,但是有一天可能会发生一些重定向(最坏的情况,例如在会议中)
    【解决方案5】:
    (function () {
    var originalFetch = fetch;
    fetch = function() {
        return originalFetch.apply(this, arguments).then(function(data) {
            someFunctionToDoSomething();
            return data;
        });
    };})();
    

    来源 Can one use the Fetch API as a Request Interceptor?

    【讨论】:

      【解决方案6】:

      当你想...

      catch (error) {
        console.dir(error) // error.response contains your response
      }
      

      【讨论】:

        【解决方案7】:
        fetch(url,{
                    method: 'GET',
                    headers,
                    body: JSON.stringify(aData)
                }).then(response => {
                    if(response.ok){
                        return response.json();
                    }
        
                    return Promise.reject(response);
                }).catch(e => {
                    if(e.status === 401){
                        // here you are able to do what you need
                        // refresh token ..., logout the user ...
                        console.log(e);
                    }
        
                    return Promise.reject(e.json());
                });
        

        【讨论】:

          猜你喜欢
          • 2019-05-22
          • 1970-01-01
          • 1970-01-01
          • 2023-01-11
          • 1970-01-01
          • 2019-09-15
          • 2018-12-02
          • 2021-08-07
          • 1970-01-01
          相关资源
          最近更新 更多