proxy_cache_bypass 是缓存绕过指令,需同时满足启用缓存、变量名正确、值非空且不为"0"/"off"三条件;必须配合 proxy_no_cache 防止污染缓存,并通过响应头或日志验证生效。

proxy_cache_bypass 不是“穿透”缓存的技术,而是让 Nginx 主动跳过缓存查找、直接回源的控制指令。所谓“缓存穿透”在这里是误用术语;真正目标是:对特定请求,不读缓存、不依赖旧内容、直连后端——这叫“缓存绕过”。
要让它真正起作用,得满足三个硬条件:缓存已启用、变量写对、值判准。缺一不可。
必须在同一 location 中启用 proxy_cache
只写 proxy_cache_bypass 没用。Nginx 会直接忽略它,除非对应 location 明确配置了:
-
proxy_cache mycache;(名称需与proxy_cache_path的keys_zone一致) -
proxy_cache_valid 200 5m;(定义哪些响应可缓存)
例如:
location /api/ {
proxy_pass http://backend;
proxy_cache mycache;
proxy_cache_valid 200 302 5m;
proxy_cache_bypass $http_x_refresh;
}
变量名必须严格匹配 Header 规则
客户端发 X-Refresh: 1,Nginx 内部变量是 $http_x_refresh,不是 $http_X_Refresh 或 $http_xrefresh。规则是:
- 全小写
- 短横
-替换为下划线_ - 前缀固定为
$http_
常见对照:
-
X-Bypass-Cache→$http_x_bypass_cache -
X-Gray-Preview→$http_x_gray_preview -
X-Refresh-Cache→$http_x_refresh_cache
值判断逻辑:非空且不等于 "0" 或 "off"
只要变量展开后满足以下任一,就触发绕过:
- 是非空字符串(如
"true"、"1"、"force"、"debug") - 不是
"0"(不区分大小写) - 不是
"off"(不区分大小写)
比如这些都有效:
-
curl -H "X-Refresh: 1" /api/data -
curl -H "X-Refresh: true" /api/data -
curl -H "X-Refresh: T" /api/data
而这些无效:
-
curl /api/data(Header 缺失 → 变量为空) -
curl -H "X-Refresh: 0" /api/data curl -H "X-Refresh: off" /api/data
多条件组合与精细控制
支持空格分隔多个变量,任意一个为真即绕过:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
按 Header 或参数触发:
proxy_cache_bypass $http_x_preview $arg_debug;
(带X-Preview头,或 URL 含?debug=1)按 IP 白名单限制:
proxy_cache_bypass $http_x_refresh $remote_addr ~^(192\.168\.10\.);-
用
map做语义化判断(推荐用于灰度/角色):map $cookie_role $skip_cache { "admin" 1; default 0; } proxy_cache_bypass $skip_cache;
生产中务必搭配 proxy_no_cache
proxy_cache_bypass 只控制“不读缓存”,默认仍会把回源响应写入缓存(只要状态码和头符合缓存规则)。这可能导致敏感数据污染缓存。
所以关键补充是:
proxy_no_cache $http_x_refresh;
两个指令变量名必须完全一致,才能确保:
✅ 不查旧缓存
✅ 不存新响应
否则一次管理员调试请求,可能把带 Token 的用户数据缓存下来,被后续无权限用户命中。
验证是否生效:看响应头和日志
别只信配置,实测才可靠:
发起带头请求:
curl -I -H "X-Refresh: 1" https://yoursite.com/api/data检查响应头:
应不含X-Cache: HIT;理想是看到X-Cache-Status: BYP(需提前加add_header X-Cache-Status $upstream_cache_status;)查 access log:
$upstream_cache_status字段应显示BYP,不是HIT或MISS
不复杂但容易忽略










