404 not found 的意思是:服务器收到了请求,但找不到对应的资源,于是返回 404 状态码。不过,你看到 404 页面并不一定代表资源真的不存在,浏览器缓存、CDN 边缘缓存、Service Worker 缓存或旧的重定向记录,都可能让你看到过期的 404 假象。排除这类假象的可靠做法是:用带随机查询串的 URL 强制绕过缓存复查,再用服务器日志和响应头确认状态码的真实来源。
源站真实 404 是服务器在磁盘或数据库里确实找不到该资源,响应头中通常带有明确的 HTTP/1.1 404 Not Found,且日志里能看到这次请求。缓存层伪造的 404 则是源站资源已经恢复或一直存在,但中间某一层把旧的 404 响应缓存下来,继续返回给访客。
两者的处理方向完全相反:前者要修资源或做重定向,后者要清缓存或调整缓存策略。所以第一步不是急着改页面,而是判断 404 到底由哪一层产生。
最直接的验证方法是在 URL 末尾加一个无意义的查询参数,让缓存键发生变化。例如原地址是:
https://example.com/page
改成:
https://example.com/page?cachebust=20240101
如果加了参数后页面正常返回 200,而不加参数仍是 404,说明问题很可能出在缓存层,而非源站资源缺失。如果两种情况都返回 404,则更可能是源站本身的问题,需要继续查文件路径、路由规则或后端逻辑。
适用条件:该方法对浏览器缓存和大多数 CDN 的边缘缓存有效。如果站点使用 Service Worker,查询串可能仍被拦截,需要在开发者工具的 Application 面板中勾选 Bypass for network 或注销 Service Worker 后再测。
打开浏览器开发者工具的 Network 面板,刷新页面,点开那条 404 请求,查看 Response Headers。重点看这几个字段:
server:显示是源站服务器还是 CDN 节点返回的。age:数值大于 0 说明该响应来自缓存,不是刚由源站生成。cache-control:如果包含较长的 max-age,说明 404 被允许缓存。x-cache 或类似自定义头:部分 CDN 会用它标注命中或回源。判断结果:出现 age 较大且 server 为 CDN 节点时,优先怀疑边缘缓存;age 为 0 或没有该字段,则更可能是源站直接返回的 404。
时间和人手有限时,按下面顺序做,每一步都能缩小范围:
age 与 server。验收标准:原 URL 在不加查询串的情况下稳定返回 200,且响应头中不再出现异常的缓存命中标记,才算假象被排除。
排查过程中,如果发现是缓存策略把 404 也缓存了,需要确认 cache-control 是否对错误状态码设置了过长的缓存时间。robots.txt 的抓取限制不等于可靠的索引移除,站点地图也不保证收录,这些和缓存假象是不同层面的问题,不要混在一起处理。
下一步:挑一个当前被报 404 的 URL,按上面的清单从加随机查询串开始测一遍,记录每一步的响应头变化,再决定是清缓存还是修资源。