Axios 如何跨域携带 Cookie?

Axios 如何跨域携带 Cookie?


一、什么是跨域?核心是"同源策略"

1. 同源的定义

同源:协议、域名、端口三者完全一致才算同源,否则就是跨域。

场景 前端页面URL 后端接口URL 是否跨域
同源 http://localhost:3000 http://localhost:3000/api
不同端口 http://localhost:3000 http://localhost:8080/api
不同域名 www.a.com api.b.com
不同协议 http://localhost:3000 https://localhost:3000/api

注意:即使 IP 相同,只要域名不同,也算跨域。


2. 为什么有跨域限制?

  • 同源策略是浏览器的安全机制,防止恶意网站窃取用户数据(如 Cookie)。
  • 跨域请求默认不会携带 Cookie,也不能访问非同源的 DOM。

二、跨域时的典型问题:Cookie 无法携带

1. 典型场景

  • 前端:web.example.com
  • 后端:api.example.com
  • 登录后后端 Set-Cookie: token=xxx; Domain=api.example.com
  • 问题:前端属于 web.example.com,Cookie 作用域是 api.example.com,浏览器不会自动携带 Cookie。

2. 常见报错

ruby 复制代码
The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

1. 前端配置(withCredentials)

推荐做法:统一封装 Axios 实例,强制 withCredentials: true

js 复制代码
import axios from 'axios';

const api = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 10000,
  withCredentials: true, // 关键
});

export default api;

或在单个请求中:

js 复制代码
axios.get('https://api.example.com/user/profile', {
  withCredentials: true
});

2. 后端 CORS 配置(以 Express 为例)

关键点:

  • Access-Control-Allow-Origin 必须是具体域名,不能是 *
  • Access-Control-Allow-Credentials: true
  • Cookie 设置 SameSite=None; Secure; Domain=.example.com
js 复制代码
const cors = require('cors');
app.use(cors({
  origin: 'https://web.example.com', // 不能是 *
  credentials: true
}));

app.post('/login', (req, res) => {
  res.cookie('token', 'abc123', {
    httpOnly: true,
    secure: true, // 生产环境必须 https
    sameSite: 'None', // 跨域必须 None
    domain: '.example.com' // 子域共享
  });
  res.json({ success: true });
});

属性 说明
domain .example.com,子域共享
path /,全站有效
httpOnly true,防止 XSS
secure true,必须 HTTPS
sameSite None,跨域必须设置

4. 开发环境代理(绕过跨域)

Vue CLI 代理示例:

js 复制代码
// vue.config.js
module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: 'https://api.example.com',
        changeOrigin: true,
        secure: false,
        pathRewrite: { '^/api': '' }
      }
    }
  }
};

前端请求 /api/user/profile,实际代理到 https://api.example.com/user/profile

注意:仅限开发环境,生产环境必须用 CORS。


5. 第三方 API 跨域(不可控后端)

方案:服务端中转

js 复制代码
// Node.js 代理
app.get('/proxy', async (req, res) => {
  const result = await axios.get('https://third-party.com/data');
  res.send(result.data);
});

前端请求自己的 /proxy,由服务端转发。


四、常见错误与安全注意事项

  1. 不能用 Access-Control-Allow-Origin: * 搭配 Cookie
  2. Cookie 必须 SameSite=NoneSecure=true 才能跨域
  3. 生产环境强制 HTTPS
  4. 限制允许的方法和请求头,避免安全隐患

五、总结表

步骤 说明
前端 withCredentials 必须设置 withCredentials: true
后端 CORS Access-Control-Allow-Origin 指定前端域名,credentials: true
Cookie 属性 SameSite=None; Secure; Domain=.example.com
生产环境 必须 HTTPS
开发环境 可用代理,生产必须 CORS

六、最佳实践建议

  • 生产环境后端精确配置 CORS
  • Cookie 设置合适的 domainsameSitesecure
  • 前端统一封装 Axios,强制 withCredentials
  • 建议用 JWT 替代 Cookie(减少跨域复杂度)

七、常见问题答疑

Q1:为什么 withCredentials 必须配合后端 CORS?

A:否则浏览器会拦截响应,Cookie 不会被设置。

Q2:为什么 SameSite=None 必须 Secure?

A:浏览器安全要求,防止 Cookie 被劫持。

*Q3:能不能用通配符

A:不能,带 Cookie 的跨域请求必须指定具体域名。


八、流程图

css 复制代码
前端(web.example.com) --withCredentials--> 后端(api.example.com)
        |                                        |
        |<--Set-Cookie: SameSite=None; Secure----|
        |                                        |
        |<--Access-Control-Allow-Origin: web.example.com
        |<--Access-Control-Allow-Credentials: true

九、参考代码片段

前端:

js 复制代码
axios.post('https://api.example.com/login', data, {
  withCredentials: true
});

后端:

js 复制代码
res.cookie('token', 'abc123', {
  sameSite: 'None',
  secure: true,
  domain: '.example.com'
});
res.header('Access-Control-Allow-Origin', 'https://web.example.com');
res.header('Access-Control-Allow-Credentials', 'true');

十、结论

  • 跨域携带 Cookie,前端 withCredentials: true,后端 CORS 配置+Cookie 属性必须正确。
  • 生产环境务必用 HTTPS,开发环境可用代理。
  • 推荐 JWT 方案,减少跨域 Cookie 的复杂度。
相关推荐
每天吃饭的羊14 分钟前
react中为啥使用剪头函数
前端·javascript·react.js
Nicholas6844 分钟前
Flutter帧定义与60-120FPS机制
前端
多啦C梦a1 小时前
【适合小白篇】什么是 SPA?前端路由到底在路由个啥?我来给你聊透!
前端·javascript·架构
薛定谔的算法1 小时前
《长安的荔枝·事件流版》——一颗荔枝引发的“冒泡惨案”
前端·javascript·编程语言
中微子1 小时前
CSS 的 position 你真的理解了吗?
前端·css
谜构1 小时前
【0编码】我使用Trae AI开发了一个【随手记账单格式化工具】
前端
G_whang1 小时前
jenkins部署前端vue项目使用Docker+Jenkinsfile方式
前端·vue.js·jenkins
ZhangApple1 小时前
微信自动化工具:让自己的微信变成智能机器人!
前端·后端
袋鱼不重1 小时前
手把手搭建Vue轮子从0到1:2. 搭建框架雏形
前端
zl_vslam2 小时前
SLAM中的非线性优化-2D图优化之激光SLAM cartographer前端匹配(十七)
前端·人工智能·算法