07 CORS Header 详解与速查

1. 请求方 Header

Origin

浏览器声明发起请求的页面源:

Origin: https://www.example.com

它只有源,没有路径。服务端可用它选择 CORS 响应,但不可把它当作身份凭据。

Access-Control-Request-Method

仅用于预检,说明正式请求准备使用的方法:

Access-Control-Request-Method: PATCH

Access-Control-Request-Headers

仅用于预检,列出正式请求准备携带的非简单 Header:

Access-Control-Request-Headers: authorization,content-type,x-request-id

2. 响应方 Header

Access-Control-Allow-Origin

Access-Control-Allow-Origin: https://www.example.com

表示浏览器可以让该源读取响应。值通常是一个具体 Origin 或 *,不是以逗号分隔的来源列表。多个来源要在服务端匹配请求的 Origin,再回显唯一匹配值。

* 适合真正公开、无需凭据的资源。它不代表认证或授权,也不能与浏览器凭据模式组合使用。

Access-Control-Allow-Credentials

Access-Control-Allow-Credentials: true

允许浏览器向跨源请求携带凭据,并向页面暴露带凭据响应。只有 true 是有效允许值。使用它时:

JWT Bearer Token 是显式请求头,不属于 Fetch credentials 开关所指的 Cookie 凭据模式;但 Authorization 会触发预检,必须被允许。

Access-Control-Allow-Methods

Access-Control-Allow-Methods: GET,HEAD,POST,PUT,PATCH,DELETE

在预检响应中声明允许的正式请求方法。它不是 Express 路由权限:即便列出 DELETE,DELETE 路由仍须认证、授权和参数校验。

Access-Control-Allow-Headers

Access-Control-Allow-Headers: Authorization,Content-Type,X-Request-Id

在预检响应中声明正式请求可携带的 Header。只表示浏览器可以发送,并不表示 Authorization 内容有效。

cors 中间件未显式配置 allowedHeaders 时,通常会根据浏览器的 Access-Control-Request-Headers 生成响应。生产项目也可以明确列出,以便审计。

Access-Control-Expose-Headers

跨源页面默认只能读取一小组安全列出的响应头。需要前端读取下载文件名、请求 ID 等信息时显式暴露:

Access-Control-Expose-Headers: Content-Disposition,X-Request-Id,X-Total-Count

它不是“把 Header 发给浏览器”:Header 原本已经抵达浏览器;它决定 JavaScript 的 response.headers 能否读取。

Access-Control-Max-Age

Access-Control-Max-Age: 600

允许浏览器缓存预检结果若干秒,减少 OPTIONS。浏览器可能设置自身上限。配置太长会使 CORS 策略变更不能立刻反映到已有客户端,因此初期可采用几分钟并逐步调整。

3. Vary: Origin 为什么重要

当服务器按 Origin 动态响应时:

Access-Control-Allow-Origin: https://a.example.com
Vary: Origin

Vary: Origin 告诉 CDN、Nginx 缓存或其他共享缓存:不同 Origin 对应不同响应版本。缺失它可能导致为 A 站生成的响应被缓存后错误地交给 B 站。

Vary 是可组合 Header。不要用 res.set("Vary", "Origin") 粗暴覆盖已有值;Express 可使用:

res.vary("Origin");

预检若根据请求 Header 动态响应,还可能出现:

Vary: Origin, Access-Control-Request-Headers

通常应让成熟的 CORS 中间件正确处理,而不是手写一组响应头。

4. Header 出现在哪个响应

Header 简单/正式响应 预检响应
Access-Control-Allow-Origin
Access-Control-Allow-Credentials 需要凭据时 需要凭据时
Access-Control-Allow-Methods 通常不必
Access-Control-Allow-Headers 通常不必
Access-Control-Expose-Headers 通常不必
Access-Control-Max-Age

5. 常见误区