如何使用 axios 检测 401 并停止控制台错误

Posted

技术标签:

【中文标题】如何使用 axios 检测 401 并停止控制台错误【英文标题】:How to detect a 401 with axios and stop the console error 【发布时间】: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 的常见做法,但我似乎无法解决。 谢谢

【问题讨论】:

How to handle 401 (Authentication Error) in axios and react?的可能重复 【参考方案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。

以上是关于如何使用 axios 检测 401 并停止控制台错误的主要内容,如果未能解决你的问题,请参考以下文章

执行带有axios的GET请求时出现401错误

如何在 Axios 中传递 Bearer 令牌

使用全局axios拦截器时如何防止出现多次401错误警告

当我一直得到 401 时,如何使用标题删除 axios?

Axios 发布请求适用于 Postman,但不适用于浏览器(它返回“错误 401-未授权”)

使用 Axios 和 Firebase 时出现 401 未经授权的错误