必须在Nginx中将$http_origin加入proxy_cache_key并添加add_header Vary Origin;若用Access-Control-Allow-Origin: *,则不应加Vary,避免缓存碎片化。

当Nginx作为反向代理缓存API响应时,若后端服务对不同Origin返回相同内容(如允许所有跨域请求),但未在响应头中设置Vary: Origin,浏览器或中间代理可能错误复用缓存——比如用户A的跨域请求缓存被用户B(不同Origin)直接命中,导致CORS失败(如Access-Control-Allow-Origin不匹配)。根本解法是在Nginx中确保带跨域响应的缓存键包含Origin,并显式添加Vary: Origin头。
确保Nginx缓存键包含Origin字段
Nginx默认缓存键不包含请求头,需手动将$http_origin加入proxy_cache_key,使不同Origin的请求走不同缓存条目:
proxy_cache_key "$scheme$request_method$host$request_uri$http_origin";
注意:$http_origin在非跨域请求中为空,会导致同一资源出现两份缓存(有Origin/无Origin)。更稳妥的做法是统一处理,例如:
- 若API始终支持跨域,强制让所有请求都参与Origin区分:用
map指令将空Origin映射为固定值(如"null") - 若仅部分路径需跨域,可针对
location块单独配置缓存键
主动添加Vary: Origin响应头
仅改缓存键不够,必须让客户端知道“该响应依赖Origin”,否则CDN或浏览器仍可能忽略Origin做缓存。在Nginx中添加:
add_header Vary Origin;
放在location块或server块内均可,建议紧邻add_header Access-Control-Allow-Origin "*";或具体Origin逻辑之后。若后端已返回Vary头,Nginx默认会继承;但为保险起见,显式设置可覆盖后端遗漏情况。
避免通配符Origin与缓存冲突(关键细节)
若使用Access-Control-Allow-Origin: *,则无需区分Origin——所有请求可共享缓存,此时Vary: Origin反而有害(导致缓存碎片化)。正确做法是:
- 明确只对简单请求(无凭证)返回
*,且不加Vary: Origin - 对带凭证(
credentials: true)的请求,必须返回具体Origin值,并配套Vary: Origin和含Origin的缓存键 - 可在Nginx中用
map根据$http_origin和$http_access_control_request_headers等变量动态控制响应头
验证是否生效
通过curl检查响应头和缓存行为:
curl -I -H "Origin: https://a.com" https://api.example.com/data curl -I -H "Origin: https://b.com" https://api.example.com/data
观察两点:
- 响应头是否含Vary: Origin
- 两次请求的X-Cache(或自定义缓存标识头)是否均为HIT(说明缓存隔离成功)或均为MIS(需排查缓存配置)
若一个HIT一个MISS,说明缓存键已区分Origin;若都HIT但Vary缺失,则需补上add_header。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










