真实面经题目 · 原创解析

跨域请求需要携带 Cookie 时,前端该怎么设置?

前端请求不一定必须携带 Cookie。是否携带取决于业务是否依赖 Cookie 做登录态、会话、灰度、风控等状态识别,以及浏览器、前端请求配置、Cookie 属性和服务端 CORS 配置是否同时满足条件。跨域场景下,前端单独设置不够,必须前后端配合:前端开启 credentials,服务端允许带凭证,并返回精确的 Access-Control-Allow-Origin 和 Access-Control-Allow-Credentials。

出现于:阿里巴巴 · 前端

60 秒回答模板

前端请求不是必须携带 Cookie,只有接口需要基于 Cookie 识别用户状态时才需要。默认情况下,同源请求通常会携带满足条件的 Cookie;跨域请求不会自动携带,需要 fetch 设置 credentials: 'include',XHR 设置 withCredentials = true,axios 设置 withCredentials: true。Cookie 本身一般由服务端通过 Set-Cookie 下发,并受 Domain、Path、SameSite、Secure、HttpOnly 等属性约束。跨域带 Cookie 时,服务端 CORS 也必须配合:Access-Control-Allow-Credentials: true,Access-Control-Allow-Origin 不能是 *,必须是具体 Origin。若是复杂请求,还会先发预检请求,预检通过后才会发真实请求。带 Cookie 的跨域请求还要考虑 CSRF 风险,通常要配合 SameSite、CSRF Token、Origin/Referer 校验等防护。

考点 是否必须携带 Cookie
主线 同源请求默认行为
易错点 认为前端请求必须携带 Cookie,忽略了接口是否依赖…

深入解析

01

是否必须携带 Cookie

不必须。Cookie 只是浏览器保存并按规则附带到请求中的一种状态机制。静态资源、公开接口、使用 Authorization Token 的接口、匿名查询接口,都不一定需要 Cookie。只有当服务端依赖 Cookie 中的 session id、登录态、实验分组、风控标识等信息时,前端请求才需要携带 Cookie。

02

同源请求默认行为

同源是协议、域名、端口都一致。浏览器请求同源接口时,只要目标 URL 匹配 Cookie 的 Domain、Path、Secure、SameSite 等规则,通常会自动携带对应 Cookie。fetch 的 credentials 默认值是 same-origin,表示同源请求带 Cookie,跨域请求不带 Cookie。

03

跨域请求前端设置

跨域请求想带 Cookie,前端必须显式开启 credentials。fetch 使用 credentials: 'include';XMLHttpRequest 使用 xhr.withCredentials = true;axios 使用 withCredentials: true,可以对单个请求设置,也可以在 axios 实例或全局默认配置中设置。需要注意,前端开启 credentials 只是允许浏览器带凭证,不代表一定会带上 Cookie,Cookie 自身属性和服务端 CORS 也必须满足。

04

Cookie 属于请求目标域

跨域请求时,浏览器携带的是请求目标域名下的 Cookie,而不是当前页面域名下的 Cookie。例如页面在 app.example.com,请求 api.example.com,浏览器判断是否携带的是 api.example.com 相关 Cookie。前端不能随意把某个域的 Cookie 发送给另一个无关域,Cookie 的发送由浏览器根据目标 URL 和 Cookie 属性控制。

05

Set-Cookie 与属性约束

Cookie 通常由服务端通过 Set-Cookie 响应头下发。Domain 决定 Cookie 可用于哪个域,未设置 Domain 时通常是 host-only,只能用于当前主机;设置 Domain=example.com 后可覆盖相关子域。Path 限制 Cookie 发送的路径范围。Secure 表示只在 HTTPS 下发送。HttpOnly 表示 JS 不能通过 document.cookie 读取或修改,但浏览器仍可在符合条件时自动携带。SameSite 控制跨站请求是否携带 Cookie,跨站带 Cookie 通常需要 SameSite=None; Secure。

06

SameSite 与跨域区别

SameSite 关注的是站点维度,CORS 关注的是 Origin 维度。Origin 是协议、域名、端口的组合;Site 通常和可注册域相关,并且现代浏览器会考虑 scheme。两个地址可能跨 Origin,但仍属于 same-site;也可能既跨 Origin 又跨 Site。面试中需要说明,跨域 Cookie 是否发送不只看 CORS,还要看 SameSite 是否允许。

07

CORS 服务端配置

跨域带 Cookie 时,服务端必须返回 Access-Control-Allow-Credentials: true,并且 Access-Control-Allow-Origin 必须是具体的请求源,不能使用 *。如果服务端根据请求 Origin 动态返回 Access-Control-Allow-Origin,通常还应配合 Vary: Origin,避免缓存污染。否则即使真实响应到了浏览器,前端 JS 也不能读取响应内容,Set-Cookie 也可能无法按预期生效。

08

预检请求

当跨域请求是复杂请求时,浏览器会先发送 OPTIONS 预检请求,询问服务端是否允许该 Origin、Method、Headers。预检通过后才会发送真实请求。预检请求本身不是业务请求,不应该依赖业务 Cookie 完成鉴权;服务端应正确响应 Access-Control-Allow-Methods、Access-Control-Allow-Headers、Access-Control-Allow-Origin 和 Access-Control-Allow-Credentials。

09

安全风险

跨域带 Cookie 会扩大 CSRF 风险,因为 Cookie 是浏览器自动携带的凭证。防护方式包括设置合适的 SameSite,使用 CSRF Token,校验 Origin 或 Referer,避免对敏感操作使用纯 GET,关键接口增加二次校验。HttpOnly 能防止 JS 读取 Cookie,降低 XSS 窃取 Cookie 的风险,但不能单独防住 CSRF。

易错点

  • 认为前端请求必须携带 Cookie,忽略了接口是否依赖 Cookie 状态。
  • 只在前端设置 withCredentials,却忘记服务端 CORS 也要允许 credentials。
  • 跨域带 Cookie 时把 Access-Control-Allow-Origin 写成 *。
  • 以为 Cookie 属于当前页面域名,忽略跨域请求发送的是目标域名下的 Cookie。
  • 手动设置 Cookie 请求头,忽略浏览器环境中 Cookie 请求头由浏览器控制。
  • 忽略 SameSite=None 必须配合 Secure,导致跨站 Cookie 不生效。

面试官追问

为什么 fetch 设置了 credentials: 'include' 还是没有 Cookie?

常见原因包括:目标域下根本没有对应 Cookie;Cookie 的 Domain 或 Path 不匹配;HTTPS 场景不满足 Secure;跨站场景 SameSite 不是 None;服务端没有返回 Access-Control-Allow-Credentials: true;Access-Control-Allow-Origin 使用了 *;浏览器限制第三方 Cookie;请求 URL 和预期域名不一致。

跨域登录接口返回 Set-Cookie,为什么浏览器没存?

需要检查响应是否通过 CORS 校验,前端是否开启 credentials,Set-Cookie 是否包含合适的 SameSite、Secure、Domain、Path,是否是 HTTPS,以及浏览器是否阻止第三方 Cookie。尤其是跨站 Cookie 通常需要 SameSite=None; Secure。

Access-Control-Allow-Credentials: true 就能跨域带 Cookie 吗?

不能。它只是服务端声明允许凭证参与 CORS。前端仍要设置 credentials 或 withCredentials,Access-Control-Allow-Origin 也必须是具体 Origin,Cookie 自身属性还要允许在该请求中发送。

为什么 Access-Control-Allow-Origin 不能写 *?

因为带凭证的跨域请求涉及用户身份。如果允许任意 Origin 读取带凭证的响应,就会造成严重数据泄露风险。规范要求 credentials 模式下不能使用通配 Origin,必须明确允许具体来源。

HttpOnly Cookie 不能被 JS 读取,那前端怎么携带它?

不需要前端读取。HttpOnly 只禁止 JS 访问 Cookie 内容,浏览器仍会在请求满足规则时自动携带它。这也是会话 Cookie 常设置 HttpOnly 的原因。