Nginx 默认因上游 Set-Cookie 直接跳过缓存,需用 proxy_ignore_headers Set-Cookie 让缓存决策忽略该头,并配 proxy_hide_header Set-Cookie 阻止透传;仅当响应无敏感数据且无 Cache-Control 禁用指令时才可安全启用。

后端响应带 Set-Cookie 是 Nginx 缓存失效最常见却最容易被误判的原因——它不是配置没起作用,而是 Nginx 的默认安全策略:只要上游返回了 Set-Cookie 头,就直接跳过缓存,不写入、不读取、不尝试。
确认是否真是 Set-Cookie 导致缓存失败
先别急着改配置,用最直接的方式验证:
- 用
curl -I请求目标 URL,观察响应头里是否有Set-Cookie:(注意大小写和冒号) - 同时检查是否有
Cache-Control: private、no-store或Expires过期等禁用缓存的头 - 在 Nginx 配置中加一句:
add_header X-Cache-Status $upstream_cache_status;,再请求两次,看响应头中是MISS还是BYPASS:
→ 出现BYPASS表示请求被主动绕过(比如含 Cookie 或 Authorization);
→ 出现MISS且重复请求仍是MISS,才更可能是Set-Cookie触发了“拒绝缓存”逻辑
判断这个 Set-Cookie 是否真的可以忽略
不能一概而论地“强制缓存”,必须人工确认安全性:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
- 响应体是否含用户私有数据?比如 HTML 里嵌了
user_id、token或 session 标识 - 这个
Set-Cookie是不是只用于统计或兼容,例如:_ga=GA1.2.xxxx、__cf_bm=xxx、空值或固定字符串dummy=1 - 接口是否全局只读?比如
/api/config、/_next/static/xxx.js,不依赖登录态也不返回个性化内容 - 响应头中没有
Cache-Control: private或Vary: Cookie等隐式禁止缓存的指令
精准配置:让缓存决策忽略,同时阻断透传
这两步缺一不可,否则缓存可能写入但污染客户端:
- 在启用缓存的
location块内、proxy_pass之前添加:proxy_ignore_headers Set-Cookie;
→ 注意:必须是Set-Cookie(首字母大写,连字符不能少),不能写成set-cookie或Set-cookie - 同步隐藏该头,防止浏览器收到并错误保存:
proxy_hide_header Set-Cookie; - 如果后端还附带其他干扰缓存的头(如
Cache-Control),可一并忽略:proxy_ignore_headers Set-Cookie Cache-Control;
验证与防护要点
改完别只看日志,要实测响应行为:
- 发起两次相同请求,确认第二次响应头出现
X-Cache-Status: HIT - 检查第二次响应中已无
Set-Cookie头(证明proxy_hide_header生效) - 临时禁用
proxy_cache_use_stale updating;,避免后台更新时旧缓存被错误复用 - 若该路径面向已登录用户,额外加上:
proxy_cache_bypass $cookie_session $cookie_logged_in;proxy_no_cache $cookie_session $cookie_logged_in;
确保带会话 Cookie 的请求完全不进共享缓存

















