如何在axios中处理401(Authentication Error)并做出反应?

Ami*_*eem 15 javascript token http-status-code-401 reactjs axios

我有一个文件request.js,其中包含axios ajax请求的包装器.我从多个反应组件调用请求函数,当其中一个请求失败时,我想刷新令牌并再次重试所有失败的请求.我可以使用拦截器,但我不知道如何实现它.请帮忙.

request.js

 var client = axios.create({
   baseURL: 'http://192.168.1.3:3000',
     headers: {
     appID: 8,
     version: "1.1.0",
     empID: localStorage.getItem('empID'),
     token: localStorage.getItem('accessToken')
    }
 });

 const request = function(options) {
 const onSuccess = function(response) {
 console.debug('Request Successful!', response);
 return response.data;
 } 
 const onError = function(error) {
    console.error('Request Failed:', error.config);
    if (error.response) {
     console.error('Status:',  error.response.status);
     console.error('Data:',    error.response.data);
     console.error('Headers:', error.response.headers);
    } else {
   console.error('Error Message:', error.message);
 }

  return Promise.reject(error.response || error.message);
 }

 return client(options)
         .then(onSuccess)
         .catch(onError);
         options
 }

 export default request;
Run Code Online (Sandbox Code Playgroud)

Pra*_*ram 36

如果你想使用拦截器处理401错误,这里是代码片段.

axios.interceptors.response.use(response => {
   return response;
}, error => {
  if (error.response.status === 401) {
   //place your reentry code
  }
  return error;
});
Run Code Online (Sandbox Code Playgroud)

  • 这有改变吗?401 响应始终未定义,我在 Axios 中收到“网络错误”... (4认同)
  • 我将 *return error* 更改为 *return Promise.reject(error);* (3认同)

est*_*ani 8

这有效:

// Add a 401 response interceptor
window.axios.interceptors.response.use(function (response) {
    return response;
}, function (error) {
    if (401 === error.response.status) {
        // handle error: inform user, go to login, etc
    } else {
        return Promise.reject(error);
    }
});
Run Code Online (Sandbox Code Playgroud)

摘自:https : //gist.github.com/yajra/5f5551649b20c8f668aec48549ef5c1f

我有这个额外的问题:

“网络错误”没有任何反应

tl;dr - 这是 CORS 及其设置方式的问题,因此 axios 从未从浏览器获取信息。您必须从服务器端对其进行排序。

描述

如果您有类似的问题,您会在浏览器控制台中看到它。浏览器将阻止您通过 ajax 访问不同的 url。

在我的特殊情况下(node.js - express)是过滤器的顺序,CORS 过滤器(开发环境)是在这个特定请求的处理程序之后添加的,所以服务器当时没有发送正确的 CORS 标头,并且因此浏览器甚至不允许发生请求(没有对服务器的任何调用,因此没有返回错误对象)。


Ami*_*eem 7

我得到了以下代码

import axios from 'axios';
import config from '../../configuration.json';
import qs from 'qs';

const baseURL = config['baseUrl_local'];
let authTokenRequest;

/**
  * @description axios instance for ajax requests
*/ 

var client = axios.create({
baseURL: baseURL,
headers: {
    appID: 8,
    version: "1.1.0",
    empID: localStorage.getItem('empID'),
    token: localStorage.getItem('accessToken')
}
});

/**
 * @description this method calls a requestNewToken method to issue a 
 new token to the client
*/ 

 function getAuthToken() {
   if (!authTokenRequest) {
   authTokenRequest = requestNewToken();
   authTokenRequest.then(resetAuthTokenRequest, resetAuthTokenRequest);
 }
 return authTokenRequest;
 }

/**
  * @description this method requests the server to issue a new token, 
  the server response is updated in local storage accessToken
*/ 

function requestNewToken() {
  var newToken = request({
  method: "post",
  url: '/sign-in',
  data:  qs.stringify({
         "userName":localStorage.getItem('userName'),
         "password":localStorage.getItem('password')
         })  
  }).then((res)=>{
  if(res.status == "success"){
    localStorage.setItem('accessToken',res.data.accessToken);
    //if featureArray is present in response object, update the 
    featureArray in local storage
    if(res.data.features){
      localStorage.setItem(
      'featureArray',
     JSON.stringify(res.data.features));
    }
    client = axios.create({
     baseURL: baseURL,
     headers: {
          appID: 8,
          version: "1.1.0",
          empID: localStorage.getItem('empID'),
          token: localStorage.getItem('accessToken')
      }
   });
 } else {
  window.location = "/logout";
 }
});
 return newToken;
}

function resetAuthTokenRequest() {
  authTokenRequest = null;
 }

/**
  * @description if any of the API gets 401 status code, this method 
   calls getAuthToken method to renew accessToken
  * updates the error configuration and retries all failed requests 
  again
*/ 

client.interceptors.response.use(undefined, err => {
  const error = err.response;
  // if error is 401 
  if (error.status===401 && error.config && 
  !error.config.__isRetryRequest) {
  // request for a new token
  return getAuthToken().then(response => {
   // update the error config with new token
   error.config.__isRetryRequest = true;
   error.config.headers.token= localStorage.getItem("accessToken");
   return client(error.config);
  });
 } 
});

/**
 * @description wrapper for making ajax requests
 * @param {object} object with method,url,data etc.
*/ 

const request = function(options) {
  const onSuccess = function(response) {
    return response.data;
  }
 const onError = function(error) {
  //console.error('Request Failed:', error.config);
   if (error.response) {
  //console.error('Status:',  error.response.status);
  //console.error('Data:',    error.response.data);
  //console.error('Headers:', error.response.headers);
  } else {
  console.error('Error Message:', error.message);
  }
 return Promise.reject(error.response || error.message);
 }

return client(options)
        .then(onSuccess)
        .catch(onError);
        options
}

export default request;
Run Code Online (Sandbox Code Playgroud)


Muh*_*zad 7

我们可以使用这种方法捕获 axios 401。

 axios.post('/add')
 .then(function (response) {...})
 .catch(function (error) {
     console.log(error.response.status) // 401
     console.log(error.response.data.error) //Please Authenticate or whatever returned from server
   if(error.response.status==401){
     //redirect to login
   }
 })
Run Code Online (Sandbox Code Playgroud)

  • 当我得到401时,错误没有响应!它也不会进入 catch 块 (4认同)

Tha*_*yen 5

我咨询了一些其他问题,这是我的代码

import axios from 'axios';

const instance = axios.create({
    baseURL: window.location.hostname === 'localhost' ? 'http://localhost:5001/api/v1' : 'https://api.mysite.com/api/v1'
});
instance.defaults.headers.common['Content-Type'] = 'multipart/form-data';

//validate response
instance.interceptors.response.use((response) => {
    return response;
}, (error) => {
        if (error.response.status === 401) {

            return window.location.href = '/login'
        }
    return Promise.reject(error);
});

// Set the AUTH token for any request
instance.interceptors.request.use(
    (config) => {
        const token = localStorage.getItem('token');
        config.headers.Authorization =  token ? `Bearer ${token}` : '';
        return config;
    }
)

export default instance;
Run Code Online (Sandbox Code Playgroud)