fastcgi_cache_bypass 通过检测变量是否非空来决定是否跳过缓存,需配合 fastcgi_no_cache 使用以避免缓存污染;关键在于选用正确的 cookie 变量(如 $cookie_phpsessid),并确保其由后端正确设置、未被浏览器拦截且名称准确。

fastcgi_cache_bypass 本身不“动态判断”,它只是检查所给变量的值是否非空——只要值不是空字符串(如 ""),Nginx 就跳过缓存,直接转发请求到 PHP-FPM。所以“根据 Cookie 动态跳过”的本质,是把能反映登录状态的 Cookie 变量(比如 $cookie_PHPSESSID)直接传给它。
关键不是写逻辑,而是选对变量
Nginx 不解析 Session,也不验证 Cookie 是否有效,只看它是否存在、是否非空。因此你要确保:
- 后端(PHP)在用户登录后确实设置了该 Cookie(如
PHPSESSID、auth_token或自定义名) - Cookie 没被浏览器拦截(如
SameSite=Lax/Strict下跨站请求可能不携带) - Nginx 配置里用的是正确的变量名(注意大小写和下划线)
常用可靠变量有:
-
$cookie_PHPSESSID—— PHP 默认会话 Cookie,登录后通常存在 -
$cookie_auth_token—— 若你用 JWT 或自定义 token 存入 Cookie,就用这个 -
$cookie_user_id—— 登录成功后由后端写入的用户标识 -
$http_cookie—— 整个 Cookie 字符串,可用于正则匹配(但不推荐直接用于 bypass,因内容复杂易误判)
正确写法示例(放在 location ~ \.php$ 块内)
fastcgi_cache_bypass $cookie_PHPSESSID; fastcgi_no_cache $cookie_PHPSESSID;
这两行配合使用才完整:
-
fastcgi_cache_bypass→ 不查缓存(跳过读) -
fastcgi_no_cache→ 不存响应(跳过写)
如果只写 bypass,后端返回的页面仍可能被缓存,下次未登录用户访问时可能看到旧的已登录页面(缓存污染)。
更灵活的组合方式(支持多条件)
你可以把多个变量连起来,任意一个非空就触发绕过:
fastcgi_cache_bypass $cookie_PHPSESSID $arg_nocache $http_pragma; fastcgi_no_cache $cookie_PHPSESSID $arg_nocache $http_pragma;
这样既支持登录态自动绕过,也保留手动调试入口:
- 访问
?nocache=1 - 发送请求头
Pragma: no-cache
注意 Cookie 名称必须准确
比如你后端设置的是 Set-Cookie: sessionid=abc123; Path=/,那就要用 $cookie_sessionid,而不是 $cookie_PHPSESSID。可通过浏览器开发者工具 → Application → Cookies 查看实际名称。
验证是否生效
加一行响应头方便调试:
add_header X-Cache-Status $upstream_cache_status;
访问已登录页面,响应头中应看到:
-
X-Cache-Status: BYPASS(说明 bypass 生效) - 绝不能是
HIT(否则缓存没绕过) - 同时检查响应头是否含
Set-Cookie,若存在且没被忽略,可能影响缓存行为(需配合fastcgi_ignore_headers Set-Cookie)
不复杂但容易忽略











