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=None 且 Secure=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 设置合适的 domain、sameSite、secure
  • 前端统一封装 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 的复杂度。
相关推荐
橙光成长5 小时前
PDF离线工具箱深度解析:4MB纯前端单文件,40+功能全本地运行,文件绝不上传
前端·pdf·1024程序员节
小poop11 小时前
CSS 基础与实战:从入门到精通网页美化
前端
Csvn13 小时前
运行时性能
前端
Never_every9914 小时前
位图转矢量工具哪个好?实测抠抠图AI位图转矢量工具
大数据·前端
paopaokaka_luck14 小时前
宠物门店经营管理系统(销售与库存联动、进货自动记账、 退换与退款关联、员工个人业绩、ECharts 经营分析、滞销识别与客户分层、宠物档案年龄计算)
前端·javascript·spring boot·mysql·echarts·mybatis·1024程序员节
空中湖14 小时前
用 React 写数据大屏:为什么我不建议用图表库
前端·react.js·前端框架
欣欣之王来了16 小时前
原始HTML插值:v-html指令的使用与安全风险
前端·学习·架构·项目·vue3教程
IT_陈寒16 小时前
Redis的LRU淘汰策略坑了我一整天
前端·人工智能·后端
计算机魔术师16 小时前
砍半价格、参数再涨,国产旗舰追到 Opus 鼻尖了
前端
特立独行的猫A16 小时前
10 MB 的桌面 AI 客户端:用仓颉 + 系统 WebView 替代 Electron
前端·harmonyos