Axios和CORS跨域请求携带cookie问题

3,286 阅读1分钟

Axios+CORS跨域请求

前端配置
import axios from 'axios'

const instance = axios.create({
    baseURL: process.env.NODE_ENV === 'development' ? config.proxy.dev : config.proxy.online,
    // ...
    withCredentials: true // 需配置为true,使请求体携带cookie
});

instance.interceptors.request.use(
    function(config){},
    function(error){}
)

instance.interceptors.response.use(
    function(response){},
    function(error){}
)
后端配置
const Koa = require('koa');
const cors = require('@koa/cors');

const app = new Koa();

app.use(cors({
    // origin不能设置为*,设置为*时与credentials为true不兼容
    origin: 'http://localhost:8090', 
    credentials: true // Access-Control-Allow-Credentials 需指定为true
}));

app.listen(3000)

设置完后,跨域请求就可以携带cookie

与MOCKJS兼容配置

项目中可能会使用mockjs,便于前端调试。

在使用mockjs时需要注意,当项目中执行Mock.mock方法时,会重写XMLHttpRequest

// mock.js
Mock.mock = function(rurl, rtype, template){
    // ...
    // 拦截 XHR
    if (XHR) window.XMLHttpRequest = XHR
    // ...
}

所以即使我们在项目中配置了开发环境不走mockjs,只要执行到任一句Mock.mock,均会把XMLHttpRequest重写,此时我们虽然设置了axioswithCredentials,也不会携带cookie

这时,解决问题的方法就有两种:

  1. 当设置mockfalse,测试不走mock数据时,不再执行Mock.mock;
  2. 手动设置MockwithCredentials;
Mock.XHR.prototype.withCredentials = true;

为了验证以上论述正确,可以拦截XMLHttpRequest验证:

(function(open){
    XMLHttpRequest.prototype.open = function(method, url, async, user, pass){
        this.addEventListener('readystatechange', function(){
            console.log(this) // MockXMLHttpRequest
        }, false);
        open.call(this, method, url, async, user, pass)
    }
})(XMLHttpRequest.prototype.open)