网站更新后仍显示旧内容,缓存该查哪一层

服务器上的文件已经换新,浏览器仍显示旧页面,先别急着把所有缓存清空。需要确认的是:这一次请求拿到的文件,究竟来自哪一层。本文适用于自己管理的网站,以下域名、IP 和文件路径均为示例,操作时换成真实的公开静态资源。

先找出真正没更新的文件

在浏览器开发者工具的“网络”中重新加载页面,找到仍旧显示的图片、CSS、JavaScript 或页面请求,记录完整 URL、状态码和响应内容。页面外观没变化,不一定是 HTML 缓存:也可能首页已经更新,却仍引用旧脚本,或者请求落到了另一台源站。

同时核对当前站点的实际目录、发布版本及资源文件名。构建输出是 app.a1b2.js,页面却请求 app.old.js,应先查 HTML 引用和发布过程。不要只看自己刚上传的那个目录,也不要把重启服务器当作清理缓存的方法。

浏览器、中间缓存与实际源站的版本定位关系示意

请求路径示意。网站未使用 CDN 或代理缓存时,中间一层可能不存在;判断要以实际配置和响应为准。

同一个地址,做浏览器与命令行对照

先在“网络”面板临时勾选“停用缓存(Disable cache)”,保持开发者工具打开再加载。查看请求是否来自内存、磁盘或 Service Worker;如果站点注册了 Service Worker,还要在“应用程序(Application)→Service Workers”检查接管情况,必要时临时使用“Bypass for network”做对照。测试结束恢复这些选项。

不要直接注销 Service Worker 或清空全部站点数据:这可能移除离线内容或登录状态。临时绕过后变新,只能说明本机测试路径发生了变化,不能证明其他访客也已拿到新版本。

在 Linux 或 macOS 终端对同一公开资源发起普通 GET,查看响应头:

curl -q --noproxy '*' -sS --max-time 15 \
  -D - -o /dev/null \
  'https://www.example.com/assets/app.js'
printf 'curl_exit=%s\n' "$?"

-q 放在首个参数位置,排除默认 curl 配置;--noproxy '*' 让本次检查直连,不经终端代理。命令会读取响应体但不保存,不能用来调用会支付、发信或写入数据的地址。连接失败时先处理报错;该命令不跟随跳转,遇到 3xx 要先查 Location。本次请求仍可能经过网站本身的 CDN 或反向代理。

响应里的线索 正确理解
Cache-Control: max-age=... 说明允许使用缓存的时间范围,不能单独证明这次命中了哪一层。
Age 可提示响应经过缓存;没有这个头,也不能反推请求一定抵达源站。
ETag、Last-Modified 用于版本验证。ETag 不是必然等于文件哈希,也不要只按时间判断内容相同。
条件请求返回304 表示可复用已存的响应内容,不是下载失败。应结合请求条件、实际内容和版本判断。

域名结果和源站结果是否一致

如果自己管理的源站允许直接访问,且为该域名提供有效 HTTPS 证书,可以指定本次连接的源站 IP 作对照:

curl -q --noproxy '*' -sS --max-time 15 \
  --resolve 'www.example.com:443:203.0.113.10' \
  -D - -o /dev/null \
  'https://www.example.com/assets/app.js'
printf 'curl_exit=%s\n' "$?"

这个方法保留 URL 中的域名、HTTP 主机名和 TLS 域名校验,只替换本次解析结果。证书报错时先核实源站的访问方式,不要添加 -k 跳过校验,也不要为排查向公网开放原本受限的源站。普通请求与定向请求必须比较同一地址的资源。

响应头只是线索,最终还要看内容。需要比对文件时,把两条命令的 -o /dev/null 分别换成两个尚不存在的本地输出文件路径,再检查文件内容或明确的版本标记。两次均可加 --compressed 让 curl 解压传输编码,但中间层若改写内容,还要排除这种差异。先确认请求成功且拿到预期资源,不能把错误页、跳转页或不完整文件拿来比较。

  • 源站也返回旧内容:继续查实际发布目录、应用生成内容和多台源站是否同步。
  • 源站新、域名旧:先核对域名是否进入预期入口,再查对应 CDN、反向代理的缓存规则与对象。
  • 两种命令行请求都新,浏览器旧:优先检查浏览器缓存、Service Worker 和页面实际引用的资源地址。

域名刚换过服务器时,结合DNS 缓存与解析路径排查,不要把解析仍指向旧站误判为内容缓存。需要确认请求有没有抵达站点,可查看网站访问日志。

修复版本更新方式,再恢复正常访问验证

仅刷新已经定位到的缓存对象,随后重新用正常浏览器设置验证。不要长期让全站关闭缓存,也不要只给自己电脑加随机参数就宣布问题解决。带内容哈希的静态资源可以采用较长缓存,并在内容变化时更换文件名;只有在有效期内确实不改内容时才适合使用 immutable。HTML 入口则应按更新频率设置重新验证或较短缓存。

no-cache 允许保存响应,但再次使用前需要验证;no-store 才是要求不保存。登录页面、订单和个人接口应按敏感内容另设策略,不能套用公共静态资源缓存。最后用另一台设备或正常浏览器会话核对页面和资源版本,再检查实际功能。