跨域缓存需将$http_origin加入proxy_cache_key并添加Vary Origin响应头,以隔离不同Origin的缓存;对credentials:true请求必须启用二者,对Access-Control-Allow-Origin:*且无凭据时可省略,须通过curl实测验证。

处理跨域请求的缓存键生成,核心是让不同 Origin 的请求不共享缓存,同时避免因冗余或错误配置导致缓存碎片化或 CORS 失败。
必须把 $http_origin 加入 proxy_cache_key
默认缓存键不含请求头,而浏览器跨域请求会携带 Origin 头。若不显式加入,Nginx 会把来自 https://a.com 和 https://b.com 的相同 API 请求当成一个缓存项,造成响应头(如 Access-Control-Allow-Origin)错配,触发 CORS 错误。
- 基础写法:
proxy_cache_key "$scheme$request_method$host$request_uri$http_origin"; - 注意:
$http_origin在非跨域请求中为空字符串,会导致同一 URL 出现“有 Origin”和“无 Origin”两份缓存;如需统一行为,可用map将空值映射为固定标识(如"null")
配套添加 Vary Origin 响应头
仅改缓存键还不够。客户端(浏览器或 CDN)需要知道该响应依赖于 Origin,否则仍可能忽略 Origin 直接复用缓存。
- 在对应 location 中添加:
add_header Vary Origin; - 若后端已返回
Vary: Origin,Nginx 默认继承;但显式设置更可靠,可覆盖后端遗漏 - 例外:当
Access-Control-Allow-Origin: *且不带凭据时,不应加Vary: Origin,否则会人为制造缓存碎片
区分是否带凭据(credentials)来精细控制
是否携带 Cookie 或 Authorization,直接影响 Access-Control-Allow-Origin 的取值规则,也决定缓存键是否必须包含 Origin。
- 对
credentials: true的请求,必须返回具体 Origin,并启用含$http_origin的缓存键 +Vary: Origin - 对简单请求(无凭据),若允许通配符
*,可不区分 Origin,缓存键中省略$http_origin,也不加Vary: Origin - 可通过
map指令结合$http_origin和$http_access_control_request_headers动态判断并设置响应头
验证是否真正生效
配置完成后必须实测,不能只看语法是否通过。
- 用
curl -I -H "Origin: https://a.com" https://api.example.com/data和-H "Origin: https://b.com"分别请求,检查响应头是否都含Vary: Origin - 观察自定义缓存状态头(如
X-Cache-Status或X-Upstream-Cache-Status),两次请求应分别命中 HIT(说明隔离成功),而非一次 HIT 一次 MISS(说明 key 未起效或被覆盖) - 临时将
proxy_cache_key设为固定值(如"debug"),确认所有请求都命中 HIT,可快速排除配置未加载问题


















