【问题标题】:How to detect a 401 with axios and stop the console error如何使用 axios 检测 401 并停止控制台错误
【发布时间】:2018-07-22 10:42:05
【问题描述】:

我正在尝试使用 axios 调用 API 并返回数据。

我有以下代码可以正常工作

axios.get('http://api/courses')
  .catch(function (error) {
    if (error.response) {
      console.log(error.response.status);
    } else {
      console.log('Error', error.message);
    }
  })
  .then(response => {
    console.log(response.data)
  });

这很好用,API 返回 200 和数据,所以在控制台中我得到了返回的数据。

但这不起作用

axios.get('http://api/courses')
  .catch(function (error) {
    if (error.response) {
      console.log(error.response.status);
    } else {
      console.log('Error', error.message);
    }
  })
  .then(response => {
    console.log(response.data)
  });

在上述调用中,我从 API 返回一个 401,我希望能够检测到它并做一些事情(我目前正在做一个 console.log)。但是在控制台中我收到以下错误:

GET http://api/courses 401 (Unauthorized)
(anonymous) @ spread.js:25
e.exports @ spread.js:25
e.exports @ spread.js:25
Promise.then (async)
r.request @ spread.js:25
r.(anonymous function) @ spread.js:25
(anonymous) @ index.js:20
(anonymous) @ (index):49


(index):58 Uncaught (in promise) TypeError: Cannot read property 'data' of undefined
at axios.get.catch.then.response ((index):58)
at <anonymous>

有没有办法捕获 401?这似乎是需要身份验证的 API 的常见做法,但我似乎无法解决。 谢谢

【问题讨论】:

标签: javascript axios


【解决方案1】:

通过error.response很容易捕捉和处理401。

error => {
    if (err.response.status) {
            props.navigation.navigate('Login');
            return;
         }
         });

【讨论】:

    【解决方案2】:

    您可以添加一个拦截器来捕获所有 401 响应。这样您就可以触发重定向或您可能需要的任何类型的操作。在这个例子中,我正在调度一个 redux 操作,它将清理一些用户数据并呈现登录表单。

    const UNAUTHORIZED = 401;
    axios.interceptors.response.use(
      response => response,
      error => {
        const {status} = error.response;
        if (status === UNAUTHORIZED) {
          dispatch(userSignOut());
        }
        return Promise.reject(error);
     }
    );
    

    【讨论】:

    • 当请求得到401响应时,在Axios实例上设置拦截器有效,但error.response仍未定义。这发生在 Axios 0.18 和 0.19 上。所以这个方法行不通。
    • 当发生带有401 状态码的失败请求并且没有为该授权飞行前请求启用 CORS 时,Axios 将无法访问实际响应。这需要在服务器上修复。此处针对 Spring Boot 提出的建议类似于任何其他 API:baeldung.com/spring-security-cors-preflight
    • 您是否只是将dispatch 扔在拦截器中间并期望它会起作用?!!!!!! jc
    • 你错过了这里的重点。这只是一段代码。为简洁起见,dispatch 函数在答案中省略的上下文中可用。
    【解决方案3】:

    添加了调试器来检查对象,所以这就是错误对象的样子。

    参考截图。右侧(范围内)

    【讨论】:

      【解决方案4】:

      对我来说(使用 axios 0.19)都可以:

      axios.interceptors.response.use(response => response, error => {
          if(error.response.status === 401) store.dispatch(logout);
          return error;
      });
      

      axios.interceptors.response.use(response => {
          if(response.status === 401) store.dispatch(logout);
          return response;
      });
      

      我添加这个是因为我在不同的来源看到了这两个版本,而且 Neil told 使用错误处理程序拦截的版本对他们不起作用,所以可能另一个对某人有帮助也是。

      【讨论】:

      • 嗨@YakovL,我已经用版本0.19.1更新了axios lib,但我仍然得到响应:在拦截器中未定义,我需要捕获状态码401,有什么解决方案吗?请告诉我。
      • @Shree 你介意创建一个新问题并在那里提供你的代码的相关位吗?
      • 效果很好!非常感谢,但我现在想了解更多。箭头函数中的错误对象是来自javascript的拦截错误吗?
      • @Taranis 这不太可能(我猜,这是一个丰富的对象),但是在源代码中找到确切的定义并不是那么简单(不过你可以自己尝试);我会使用控制台查看真正传递的内容,并阅读docs
      猜你喜欢
      • 1970-01-01
      • 2021-07-15
      • 2020-12-16
      • 2021-10-14
      • 2019-01-29
      • 2018-11-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多