Vue.js和Axios - 在401状态下重定向

26

我正在使用 Vue.jsaxios,并尝试创建一个通用的 API 对象,如下所示:

import router from './router'
import auth from './auth'
const axios = require('axios')

export const API = axios.create({
  baseURL: `https://my-api.com/`,
  headers: {
    Authorization: auth.getToken()
  }
})

API.interceptors.response.use(null, function (error) {
  if (error.response.status === 401) {
    console.log('Failed to login')
    router.push('/Login')
  }
  return Promise.reject(error)
})

每当收到401错误代码时,我都希望将用户重定向到我的单页应用程序中的Login屏幕。但是我没有被重定向,而且在Chrome的开发人员工具中也没有出现错误。我确实获得了带有Failed to loginconsole.log


1
我猜测状态码存储在 error.response.status 下面,请尝试一下。 - Sebastian Richter
更新了带有error.response.status和一些console.log的问题。 - Alfred Balle
好的,那么也许您可以发布您的router.js代码。拦截器看起来很不错。 - Sebastian Richter
你能发布你的 router.js 文件吗? - Ru Chern Chong
请查看 https://dev59.com/paDia4cB1Zd3GeqPFo9s#43175433。 - Eduardo Cuomo
3个回答

48

我检测到了类似的情况。我已经用这段代码进行了修复:

import router from 'router'
import store from 'store'
...
...
axios.interceptors.response.use(function (response) {
  return response
}, function (error) {
  console.log(error.response.data)
  if (error.response.status === 401) {
    store.dispatch('logout')
    router.push('/login')
  }
  return Promise.reject(error)
})

4
对我很有用,但是401代码存在于error.response.status而不是error.response.data.error.statusCode - vaughanos

6
您可以按照以下方式进行操作:
axios.post("quote", params)
  .catch(function(error) {
    if (error.response && error.response.status === 401) {
      window.location.href = "logon";
    } else {
      // Handle error however you want
    }
  });

来源:https://github.com/axios/axios/issues/396#issuecomment-395592900

这是一个关于Axios库的问题讨论,主要讨论了如何访问响应头中的Cookie信息。解决方法是通过设置`withCredentials`配置项为`true`来携带Cookie信息。此外,还介绍了如何使用`responseType: 'blob'`来处理二进制数据(比如文件下载)。
此外,该评论还介绍了如何在Axios库中进行单元测试,并提供了相应的代码示例。

3
你最终可能会得到成千上万个重复代码的位置。不好。 - Jason G

5
您可以使用以下代码,并将httpClient.js文件添加到您的项目中:
import axios from 'axios';
import {
  authHeader
}
from '../helper'

const baseUrl = 'http://localhost:8811/api/';//local-test
const Api_Path = `${baseUrl}/`;

const httpClient = axios.create({
  baseURL: Api_Path,
  headers: {
    //Authorization: 'Bearer {token}',
    //timeout: 1000, // indicates, 1000ms ie. 1 second
    "Content-Type": "application/json",

  }
})
const authInterceptor = (config) => {
  config.headers['Authorization'] = authHeader();
  return config;
}
const errorInterceptor = error => {


// check if it's a server error
  if (!error.response) {
    //notify.warn('Network/Server error');
    console.error('**Network/Server error');
    console.log(error.response);
    return Promise.reject(error);
  }

  // all the other error responses
  switch (error.response.status) {
    case 400:
      console.error(error.response.status, error.message);
      //notify.warn('Nothing to display', 'Data Not Found');
      break;

    case 401: // authentication error, logout the user
      //notify.warn('Please login again', 'Session Expired');
      console.error(error.response.status, error.message);
      localStorage.removeItem('token');
      localStorage.removeItem('user');
      //router.push('/auth');
      break;

default:
  console.error(error.response.status, error.message);
  //notify.error('Server Error');



 }
  return Promise.reject(error);
}
httpClient.interceptors.request.use(authInterceptor);
httpClient.interceptors.response.use(responseInterceptor, errorInterceptor);

export default httpClient;

另一个答案相比,这个的本质区别是什么?两者都使用了interceptors.response - Julian
1
非常感谢您的有用的提示。非常感谢。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接