
登录成功了,页面却仍显示“请登录”;刷新后偶尔正常,换个浏览器又出问题。如果站点同时启用了 WordPress 缓存插件、Nginx 页面缓存和 CDN,应先确认:这次请求到底带了登录 Cookie,还是被某一层缓存当成游客请求处理了。
这篇文章针对完整 HTML 页面的缓存。Redis 对象缓存、数据库缓存与页面缓存的排查方式不同,不能因为装了 Redis 就直接清空整个缓存库。若已发现甲用户能看到乙用户的账户内容,应立即停止相关页面的共享缓存,并处理可能的数据泄露,不要只把它当成显示故障。
先判断:没有登录,还是登录后的页面拿错了
在浏览器开发者工具的 Network 面板里,找到发生问题的页面请求,检查以下内容:
- 页面请求是否带有当前域名的
wordpress_logged_in_前缀 Cookie。 - 最终请求域名是否与登录时一致,例如登录在
www.example.com,页面却跳到了example.com。 - 页面响应是否有
Age、CF-Cache-Status、X-Cache等缓存线索。 - 同一页面在游客窗口、登录账户 A 和测试账户 B 下,各自应显示什么内容。
WordPress 使用带有站点哈希后缀的登录 Cookie;写绕过规则时通常需要匹配前缀,不能把别人站点的完整 Cookie 名称复制过来。[1]
请求没有携带登录 Cookie,应先查 Cookie 的 Domain、Path、Secure 属性及跳转后的主机名。也要检查登录是否已经过期。只有实际带着登录状态的请求仍返回游客 HTML,才继续查页面缓存。
无痕窗口能用、普通窗口不能用,只能缩小问题范围,不能单凭这一点认定是 CDN 故障。
按请求路径逐层确认缓存
常见请求路径如下,实际部署可能只有其中一部分:
浏览器 → CDN → Nginx 页面缓存 → WordPress 缓存插件 → PHP / WordPress
浏览器里勾选 Disable cache,主要用于排除浏览器本地缓存,不会替你绕过 CDN 和源站缓存。按路径逐层检查,比同时清空所有缓存更容易找到原因。
可以在自己管理的服务器或终端上,对公开页面执行普通 GET 请求:
# 将示例域名替换为自己的站点;响应正文不输出到终端
curl -sS -D - -o /dev/null 'https://example.com/sample-page/'
连续请求两次,比较 Age 与缓存状态。这里没有登录 Cookie,结果只代表游客请求,不能用来证明登录页面已正确绕过缓存。登录态检查建议直接在浏览器里做,避免把 Cookie 写进终端历史、日志或截图。
HIT 表示相应缓存层报告命中;缺少缓存状态头并不证明没有缓存。CDN 报告 DYNAMIC 或 BYPASS 时,也不能排除源站已经返回缓存页面。缓存头必须和请求 Cookie、页面内容一起判断。[4]
若要对比源站,可在授权环境中使用 curl --resolve 保留正确的主机名和 HTTPS 校验。源站限制了 CDN IP 时,不要为了测试把它临时开放给整个互联网,也不要用 -k 掩盖证书问题。
WordPress 缓存插件:先检查登录用户与动态页面
不同插件的选项名称不同,先找“缓存已登录用户”“用户缓存”“排除 Cookie”“排除 URL”等设置。
普通内容站的稳妥起点,是不对已登录用户使用共享页面缓存。部分插件支持按用户隔离缓存,但启用前需要核对插件说明及实际输出,不能把“支持登录用户缓存”理解成“可以让所有用户共用同一份 HTML”。
账户、登录、后台和结账等页面应进入动态内容排除规则。WooCommerce 站点还应检查购物车、结账和我的账户页;这些页面的路径可以自定义,不一定恰好是 /cart/、/checkout/ 和 /my-account/。[3]
WooCommerce 官方列出了与购物车和会话相关的 Cookie,例如:
woocommerce_items_in_cart
woocommerce_cart_hash
wp_woocommerce_session_
配置插件或 CDN 时,应按它们的实际匹配语法处理这些名称或前缀。仅排除 WordPress 登录 Cookie,可能遗漏尚未登录但已经建立购物车会话的访客。[3]
规则修正后再清理插件的页面缓存。一般不需要删除 Redis 数据,也不应顺手重置所有插件设置。
Nginx:绕过读取缓存与禁止写入缓存都要检查
如果站点确实启用了 Nginx 页面缓存,需要区分两种情况:反向代理缓存通常使用 proxy_cache;直接把请求交给 PHP-FPM 的部署可能使用 fastcgi_cache。两套指令不能混写。
以反向代理缓存为例,proxy_cache_bypass 决定是否从缓存读取响应,proxy_no_cache 决定是否把响应保存到缓存。登录请求只绕过读取、却仍可能把私人响应写入共享缓存,不是完整的保护措施。应检查两项是否使用一致的登录、会话及动态页面判断。[2]
还要核对现有配置是否忽略了源站的 Cache-Control、Set-Cookie 或 Vary。Nginx 文档说明,正常情况下带 Set-Cookie 的上游响应不会被缓存,但相关处理可以被配置改变;不能只看 PHP 已发送这个响应头就认为一定安全。[2]
不要为了排查直接往线上粘贴一整段通用 Nginx 配置。面板生成的配置、现有 location 匹配和缓存区域定义都可能不同。修改前备份实际加载的配置,在支持以下命令的 Nginx 环境中先测试,再平滑重载:
sudo nginx -t
# 只有上一条测试成功后,才执行重载
sudo systemctl reload nginx
使用容器、其他服务管理器或面板的站点,应按对应部署方式操作。语法测试通过,只说明配置可以解析,随后仍需验证登录态内容。
CDN:检查 HTML 缓存规则及其优先级
普通页面被错误命中共享缓存时,检查 CDN 是否有“缓存所有内容”、忽略源站响应头,或者覆盖整个站点的 HTML 缓存规则。
需要核对的规则范围包括:
- 登录、后台、账户和结账等动态路径。
- 带登录 Cookie、购物车 Cookie 或应用会话标识的请求。
- 带
Authorization的认证请求,以及相关 API 端点。 - 会改变响应内容的查询参数。
不能把所有查询参数都从缓存键里移除。若参数会改变用户看到的内容,同一个缓存键可能对应不同页面。也不必为所有带参数的公共页面永久禁用缓存,应根据应用行为逐项处理。
Cache-Control: no-cache 允许存储响应,但使用前通常需要重新验证;no-store 表示不要存储,private 针对共享缓存限制存储。WordPress 当前的禁缓存头函数包含 no-store 和 private,不过具体页面是否调用该函数、插件是否覆盖响应头、CDN 是否遵循这些头,都需要实查。[4][5]
CDN 的套餐、规则表达式与优先级存在差异。保存后应重新查看最终生效规则,并清除相关 URL 的旧缓存;大范围全站清缓存可能带来短时回源压力,不应当作每次排查的默认动作。
用游客与两个测试账户验收
修正规则后,按下面的顺序检查同一组页面:
- 用游客窗口访问公开文章和账户页面,记录预期表现。
- 用测试账户 A 登录,确认页面显示 A 的状态,检查 Cookie 与响应头。
- 用独立浏览器配置或另一台设备登录测试账户 B,确认不会出现 A 的内容。
- 退出 A 后再次访问,确认退出后的页面不保留 A 的私人信息。
- 电商站点再测购物车、结账和订单页,包括未登录的购物车会话。
测试账户不应含真实敏感信息。若怀疑已有私人内容被缓存,先阻止继续命中并清理相关副本,再做验收。
验收目标是:公开页面按设计使用缓存,登录与会话相关页面正确绕过共享缓存,账户之间没有内容串用。游客页面清缓存后暂时恢复,并不能证明问题已经解决。
故障复发时,保留这些记录
保存发生问题的 URL、时间、是否登录、请求是否带会话 Cookie,以及每层返回的缓存状态。不要记录完整 Cookie 值、认证令牌或真实订单详情。
如果只有某一种语言、设备或 URL 参数组合出问题,应检查缓存键是否区分这些会影响内容的条件。若每次开启新的加速规则就复发,先回退那条规则,保留其他公共页面的缓存。这样既能恢复正确的登录页面,也不会把所有请求长期推回 PHP。
官方参考资料
资料核验日期:2026 年 10 月 9 日。本文未在你的生产环境执行配置修改或实测,命令与排查路径需按实际部署调整。
[1] WordPress:Cookies — https://developer.wordpress.org/advanced-administration/wordpress/cookies/
[2] Nginx:HTTP proxy module — https://nginx.org/en/docs/http/ngx_http_proxy_module.html
[3] WooCommerce:Configuring caching plugins — https://woocommerce.com/document/configuring-caching-plugins/
[4] Cloudflare:Cache-Control — https://developers.cloudflare.com/cache/concepts/cache-control/
[5] WordPress:wp_get_nocache_headers() — https://developer.wordpress.org/reference/functions/wp_get_nocache_headers/




