Fetch 默认不携带 Cookie,即 credentials: 'omit',同源或跨域均不发送也不接收 Cookie;需显式设置 credentials: 'include' 或 'same-origin' 才能携带,且跨域时服务端须配置 Access-Control-Allow-Credentials: true 和精确的 Access-Control-Allow-Origin。

Fetch 的默认凭证行为是 credentials: 'omit',即无论同源还是跨域,都不发送 Cookie,也不接收服务端 Set-Cookie 响应头。这个行为从规范确立起就是默认值,2020 年初曾有部分浏览器短暂尝试改为 same-origin,但主流实现(包括当前 Chrome、Firefox、Safari)已回归并稳定维持 omit 为默认值。
如何快速确认当前 fetch 是否带 Cookie
打开浏览器开发者工具 → Network 面板 → 找到对应请求 → 查看 Request Headers → 检查是否存在 Cookie 字段:
- 没写
credentials选项 → 一定不出现 Cookie(即使页面和接口同域) - 写了
{ credentials: 'same-origin' }→ 同源时有 Cookie,跨域时没有 - 写了
{ credentials: 'include' }→ 请求头里一定有 Cookie(前提是浏览器已存该域名的 Cookie)
credentials 取值对跨域 Cookie 的实际影响
跨域场景下,credentials 不仅控制客户端是否发 Cookie,还直接决定服务端响应能否被 JS 读取:
-
omit:跨域请求完全“匿名”,不发 Cookie,也不受 CORS 凭证限制;响应可读,无需额外响应头 -
same-origin:跨域时等同于omit,不发 Cookie;服务端无需配置 Access-Control-Allow-Credentials -
include:跨域时强制发 Cookie,但浏览器会严格校验响应头:
→ 必须返回Access-Control-Allow-Origin: https://your-site.com(不能是*)
→ 必须返回Access-Control-Allow-Credentials: true
→ 缺一不可,否则响应被浏览器静默拦截(fetch 报错,response.status 不可读)
为什么同源 fetch 也不带 Cookie?常见误解澄清
很多开发者以为“同域就自动带 Cookie”,这是把表单提交或 XMLHttpRequest 的行为套用到了 fetch 上。Fetch 的设计哲学是显式优于隐式:
- 表单提交、img/script 标签:浏览器自动携带同域 Cookie,无法关闭
- XMLHttpRequest:默认携带凭证(
withCredentials = false才关闭) - Fetch:默认关闭凭证(
credentials = 'omit'),必须主动开启
这种差异是为了防范 CSRF——避免前端代码在无感知下滥用用户身份发起敏感操作。
服务端配合要点(尤其跨域 + include 场景)
仅前端设 credentials: 'include' 不够,后端响应必须同时满足:
-
Access-Control-Allow-Origin设为具体协议+域名(如https://app.example.com),禁止通配符 Access-Control-Allow-Credentials: true- 若涉及跨站 Cookie(如前端在
https://a.com调用https://api.b.com),服务端 Set-Cookie 头需含:
→SameSite=None
→Secure(强制 HTTPS)
三项缺一,浏览器就会拒绝将响应暴露给 JavaScript。


















