开发者问题收集

Axios 拦截器令牌标头存在于配置中,但不存在于请求标头中

2017-12-27
6330

我创建了 axios 拦截器,它负责在每个请求发送到我的 rest API 之前添加令牌。

import axios from 'axios';
import { store } from '../store/store';

export default function execute() {
    axios.interceptors.request.use(function(config) {
        const token = store.state.token;
        if(token) {
            config.headers.Authorization = `Bearer ${token}`;
            console.log(config);
            return config;
        } else {
            console.log('There is not token yet...');
            return config;
        }
    }, function(err) {
        return Promise.reject(err);
    });
}

正如您在第 2 行看到的,我正在导入 vuex 存储,这实际上是存放我的令牌的地方。在第 8 行中,我实际上将此令牌添加到 config 对象,然后在下一行中对其进行了控制台处理。

它在我的 main.js 文件中执行,如下所示:

import interceptor from './helpers/httpInterceptor.js';
interceptor();

令牌存在于控制台中看到的配置对象中(因为我控制台了 config 对象):

img

每次我按预期向 rest API 发出请求时,它都会运行。如果令牌存在(登录后),它应该将令牌标头添加到每个请求中。不幸的是,虽然它存在于配置对象中,但它并没有添加它,这让我有点困惑。

正如我在网络选项卡中看到的那样,它实际上并没有将令牌添加到实际请求中:

imgd

这个截图当然是在登录后拍摄的,所以令牌已经在 vuex 存储中,并且在我执行注销函数(调用 rest API)后,它控制台输出配置(拦截器的一部分)。

结果,因为我没有发送令牌,所以我的 rest API 响应了 400(错误请求)状态。

编辑!!!

我在想我可以添加什么来使它变得更好。我认为创建演示插件是不可能的,所以我决定创建一个小的 存储库 演示,您可以下载并亲眼看看问题。我希望它能帮助解决问题!

2个回答

我搞明白了。

我不知道有一种叫做预检请求的东西,它在对 rest API 进行实际请求之前执行。如果预检请求失败,它将不会接受/接收更多标头。这就是为什么我没有在 chrome 控制台网络选项卡中的实际请求中看到它,但它在拦截器中被 console.log 记录的配置对象中。

存储库演示中也是如此,它调用了不存在的 URL,因此预检请求也在那里失败了。在创建这个演示时,我不知道存在预检请求这样的东西,所以我确信无论我调用的是某个现有的 URL 端点还是虚构的端点都没关系,我认为无论哪种方式我都应该能够在那里看到请求标头。

BT101
2018-01-01

您还可以操纵过期时对清理令牌的响应。

  axios.interceptors.response.use(function (response) {
    return response;
  }, function (error) {
    if (401 === error.response.status) {
      console.log("Session Expired")
      //window.location = '/login'
    } else {
      return Promise.reject(error);
    }
  });
Marcelo Cintra de Melo
2018-05-05