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 的复杂度。
相关推荐
Lsx_11 分钟前
MultiRepo 和 Monorepo:代码管理的演进与选择
前端·javascript·架构
潘多编程22 分钟前
构建企业级Web应用:AWS全栈架构深度解析
前端·架构·aws
裕波25 分钟前
Vue 与 Vite 生态最新进展:迈向一体化与智能化的未来
前端·vue.js
destinying42 分钟前
当部分请求失败时,前端如何保证用户体验不崩溃?
前端·javascript·程序员
幼儿园技术家1 小时前
Diff算法的简单介绍
前端
陈随易1 小时前
为VSCode扩展开发量身打造的UI库 - vscode-elements
前端·后端·程序员
叁金Coder1 小时前
业务系统跳转Nacos免登录方案实践
前端·javascript·nginx·nacos
蓝倾1 小时前
京东商品销量数据如何获取?API接口调用操作详解
前端·api·fastapi
stoneship1 小时前
满帮微前端
前端
GKDf1sh1 小时前
【前端安全】聊聊 HTML 闭合优先级和浏览器解析顺序
前端·安全·html