nginx 缓存默认拒绝含 set-cookie 的响应以防会话泄露,需用 proxy_ignore_headers set-cookie 启用缓存,再以 proxy_hide_header set-cookie 防止透传,并配置 proxy_cache_key 包含 $args 保证参数区分,最后通过 x-cache-status 验证命中且禁用 stale 复用。

Nginx 缓存层默认拒绝缓存任何带 Set-Cookie 响应头的响应,这是出于安全考虑——防止将用户私有会话数据(如 session ID、CSRF token)错误地共享给其他用户。但这个机制在实际中常被误触发,比如后端静态接口或监控接口误加了无害的 Set-Cookie(如 _ga、_gid),导致本可缓存的内容被跳过。要让缓存真正生效,需明确干预 Cookie 相关行为。
缓存决策:用 proxy_ignore_headers 覆盖默认拦截
Nginx 判断是否缓存,不是看 Set-Cookie 是否存在,而是看它是否出现在“禁止缓存头列表”里。默认该列表包含 Set-Cookie 和 Authorization。要启用缓存,必须显式告诉 Nginx 忽略它:
- 必须写在启用缓存的 location 块内,且位于 proxy_pass 之前
- 指令为 proxy_ignore_headers Set-Cookie(大小写敏感,不能写成 set-cookie)
- 可同时忽略多个头,例如:proxy_ignore_headers Set-Cookie Cache-Control
- 仅影响缓存判定逻辑,不删除也不修改响应头本身
响应透传:用 proxy_hide_header 防止 Cookie 泄露
忽略 Set-Cookie 只是让缓存发生,但原始响应头仍会原样返回给客户端。这可能导致浏览器保存不该有的 Cookie,甚至引发跨用户污染。因此必须配套隐藏:
- 添加 proxy_hide_header Set-Cookie,彻底移除该头的透传
- 若后端还设置了其他不应暴露的头(如 X-Debug、X-RateLimit),也可一并 hide
- 注意:proxy_hide_header 不影响 upstream 的原始响应,只控制发给 client 的内容
缓存键设计:避免因查询参数导致错乱
即使 Set-Cookie 问题已解决,若缓存键(proxy_cache_key)未包含 $args,所有带查询参数的请求(如 /api/data?id=1 与 /api/data?id=2)会被视为同一缓存项:
- 默认 key 是 $scheme$proxy_host$uri,不含参数
- 建议显式定义:proxy_cache_key "$scheme$proxy_host$uri$is_args$args"
- 对含敏感参数(如 token、auth_code)的接口,应排除在缓存之外,而非依赖 key 过滤
验证与兜底:确认命中并防止 stale 错误复用
配置生效后,需验证缓存是否真实起效,并防范后台更新时的异常行为:
- 添加 add_header X-Cache-Status $upstream_cache_status,通过响应头观察 HIT/MISS/MISS
- 禁用 proxy_cache_use_stale updating,避免缓存更新期间旧版本(可能含误设 Cookie)被错误返回
- 搭配 proxy_cache_valid 200 302 10m 明确设置有效时间,避免无限期缓存











