axios 的 withCredentials 到底做了什么?

一、核心结论

withCredentials 是 axios 中控制跨域请求是否携带凭证(Cookie、HTTP 认证信息、TLS 客户端证书等) 的布尔值配置项,本质是对浏览器 XMLHttpRequest.withCredentials 原生属性的封装,默认值为 false

简单说:

  • withCredentials: false(默认):跨域请求时,浏览器不会携带目标域名下的 Cookie/认证信息;
  • withCredentials: true:跨域请求时,浏览器主动携带目标域名下的 Cookie/认证信息,且服务端响应的 Set-Cookie 也会生效。

注意:该配置仅对跨域请求有效,同域请求不受影响(默认携带凭证)。

二、底层原理:浏览器的同源策略 & CORS 规范

要理解 withCredentials,必须先明确浏览器的核心规则:

1. 同源策略的限制

浏览器默认禁止跨域请求携带凭证(比如 A 域名请求 B 域名接口时,不会带 B 域名的 Cookie),这是为了防止第三方网站盗用用户的认证信息。

2. CORS 规范对凭证的要求

当前端设置 withCredentials: true 时,必须满足服务端+客户端双向配置,否则请求会被浏览器拦截:

必要配置
前端(axios) withCredentials: true
服务端 响应头必须包含: 1. Access-Control-Allow-Credentials: true 2. Access-Control-Allow-Origin 不能为 *(必须是具体域名,如 https://xxx.com

三、withCredentials 具体行为拆解

1. 当 withCredentials: false(默认)

  • 请求阶段:浏览器发送跨域请求时,不会携带目标域名的 Cookie、Authorization 头等凭证;
  • 响应阶段:即使服务端返回 Set-Cookie 响应头,浏览器也不会保存该 Cookie(相当于忽略);
  • 场景:无需用户认证的跨域请求(如公开接口、静态资源)。

2. 当 withCredentials: true

  • 请求阶段:浏览器主动携带目标域名下的 Cookie(仅该域名的 Cookie,非当前域名)、HTTP 认证信息(如 Basic Auth);
  • 响应阶段: ✅ 若服务端返回 Access-Control-Allow-Credentials: true + 具体的 Access-Control-Allow-Origin:浏览器会保存服务端的 Set-Cookie,且后续请求会自动携带; ❌ 若服务端未满足上述条件:浏览器会触发 CORS 错误,拦截响应(控制台报错:Access to XMLHttpRequest at 'xxx' from origin 'xxx' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include');
  • 场景:需要用户登录态的跨域请求(如登录后获取用户信息、提交订单)。

四、典型使用场景 & 示例

场景:前端(http://localhost:3000)请求后端(http://api.example.com)的登录接口

javascript 复制代码
// axios 配置(前端)
axios({
  url: 'http://api.example.com/user/info',
  method: 'GET',
  withCredentials: true, // 跨域携带 Cookie(后端域名下的登录 Cookie)
})
.then(res => console.log(res))
.catch(err => console.log(err));

服务端配置(以 Node.js/Express 为例)

javascript 复制代码
const express = require('express');
const app = express();

// 跨域中间件配置
app.use((req, res, next) => {
  // 允许指定前端域名跨域(不能用 *)
  res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
  // 允许携带凭证
  res.setHeader('Access-Control-Allow-Credentials', 'true');
  // 允许的请求头
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
  next();
});

// 接口返回用户信息(依赖 Cookie 中的登录态)
app.get('/user/info', (req, res) => {
  res.json({ name: '张三', id: 123 });
});

app.listen(8080);

五、常见坑点

  1. Access-Control-Allow-Origin 不能为 * : 若服务端设置 *,同时前端开了 withCredentials: true,浏览器会直接拦截请求(因为 * 无法和具体域名的凭证绑定)。

  2. 跨域 Cookie 的 SameSite 限制 : 若服务端设置的 Cookie 的 SameSiteStrict/Lax,跨域请求时即使开了 withCredentials,Cookie 也可能无法携带(需设置 SameSite=None; Secure,且请求必须是 HTTPS)。

  3. 凭证仅对目标域名生效 : 比如前端 a.com 请求 b.comwithCredentials: true 只会携带 b.com 的 Cookie,而非 a.com 的 Cookie。

  4. 预检请求(OPTIONS)也需配置 : 复杂请求(如 POST 带 JSON、自定义头)会先发送 OPTIONS 预检请求,服务端必须对 OPTIONS 请求返回相同的 CORS 配置(尤其是 Access-Control-Allow-Credentials)。

六、总结

withCredentials 的核心作用是突破浏览器同源策略对跨域凭证的限制,让跨域请求能携带 Cookie/认证信息,但必须配合服务端的 CORS 配置才能生效。它是实现跨域登录态保持的关键配置,也是处理跨域认证请求的必备项。

相关推荐
Pedantic1 小时前
SwiftUI 手势层级(Gesture Hierarchy)详解
前端
飘尘1 小时前
前端转型全栈(Java后端)的快速上手指引
前端·后端·全栈
一颗烂土豆1 小时前
Meshopt 压缩深度解析,为什么它比 Draco 更快
前端·javascript·webgl
浏览器工程师2 小时前
AI Agent 接浏览器任务,先别让它一路点到底
前端·后端
雨季mo浅忆2 小时前
VSCode自动格式化三要素
前端
爱勇宝3 小时前
深扒 Anthropic 1680 位工程师简历:应届生几乎没机会,AI 公司最缺的不是博士
前端·后端·程序员
kyriewen4 小时前
同事每天催我 Code Review,我写了个脚本让 AI 替我 review PR——现在他反过来催 AI 了
前端·javascript·ai编程
user20585561518136 小时前
Windows 项目安装时报 `node-sass` 错误,如何快速处理
前端
LiaCode6 小时前
Redis 在生产项目的使用
前端·后端