先给结论:当错误页面返回 200 而不是 404 时,不能只看页面正文是否写着“找不到”,也不能只看响应状态码是否等于 200。要核对的是“服务端实际返回的状态码”和“页面主体内容是否属于错误页”这两条线是否同时成立。若两者矛盾,优先怀疑软 404:内容确实是错误提示,但状态码被错误地设成 200。核对顺序是先用不执行脚本的方式取响应头,再取渲染后的正文,最后比较两者是否指向同一类页面。
这类情况常见于两类实现。第一类是把错误页当成普通页面输出,模板里写了“页面不存在”,但路由层没有把响应码改成 404。第二类是前端接管了路由,服务器对所有未知路径都返回同一个 200 壳页面,真正的错误提示由脚本在浏览器里渲染出来。两种做法看起来都能让用户看到错误说明,但对外部抓取和缓存系统传递的信号完全不同。
要区分它们,不能只靠浏览器地址栏或页面截图。浏览器展示的是渲染后的结果,可能已经经过脚本改写;而状态码来自服务器响应,和脚本无关。把这两者分开采集,才能判断问题出在哪一层。
如果错误页由服务端模板输出,但代码里只调用了渲染方法,没有显式设置响应状态,就会默认返回 200。典型表现是:用命令行请求一个不存在的路径,返回头里是 HTTP/1.1 200 OK,而正文里包含“404”或“页面不存在”等字样。
这种情况下,页面内容和状态码不一致的根源在服务端。核对动作是:取一次响应头,确认状态码;再取一次正文,确认是否包含错误页特征文本。若正文是错误页、状态码是 200,就可以判定为软 404。下一步应检查路由处理逻辑,而不是去改页面文案。
如果站点是前端渲染,服务器可能对所有路径都返回同一个 200 的 HTML 壳,错误提示由客户端脚本根据路径判断后插入。此时响应头里的状态码是 200,正文里也看不到错误提示,因为提示还没被脚本渲染出来。
这种情况下,仅看原始响应会误以为页面正常。核对动作是:先取原始响应,记录状态码和正文;再用能执行脚本的方式取渲染后的正文,确认是否出现错误提示。若原始正文没有错误特征、渲染后才出现,说明错误提示由前端生成,而服务器状态码没有跟着变。下一步要判断是否需要在服务端为未知路径单独返回 404,而不是只依赖前端提示。
关键证据是“错误提示出现在哪一层”。可以用下面这组对照来判断:
这些证据只能说明现象出现在哪一层,不能单独证明某一种实现一定正确。比如,原始正文没有错误提示,也可能是错误页被缓存或压缩后不易识别,所以还要结合响应头和渲染结果一起看。
假设某站点有一个自定义错误页,团队有两种选择。做法 A:服务端对未知路径返回 404,并输出错误页正文。做法 B:服务端统一返回 200,由前端脚本显示错误提示。
做法 A 的代价是需要改路由逻辑,可能影响已有缓存和监控规则;收益是状态码和内容一致,外部系统能直接判断这是错误页。做法 B 的代价是状态码与内容不一致,抓取和缓存系统可能把错误页当成正常页面处理;收益是前端改动较小,适合纯前端路由的项目。
选择条件可以这样定:如果站点依赖外部系统按状态码判断页面有效性,优先做法 A;如果站点是纯前端应用且暂时无法改服务端,至少要在监控里单独记录这类软 404,避免把它当成正常页面统计。无论选哪种,都要先用同一路径分别取响应头和渲染正文,确认当前实际行为,再决定改哪一层。
robots.txt 的抓取限制不等于可靠的索引移除,即使错误页被 robots.txt 挡住,也不代表它不会被以其他方式处理。站点地图不保证收录,错误页不应放进站点地图来“纠正”状态码问题。HTTPS 不保证安全无漏洞或排名,它和状态码是否正确没有直接关系。不同搜索引擎对软 404 的支持和判断方式须分别核查,不能用一个平台的表现推断另一个平台。
另外,请求量或抓取量归零不能单独证明状态码设置正确,也可能是抓取预算变化、路径不再被引用或监控口径调整。核对时应保留响应头和正文两份证据,再结合访问日志判断影响范围。这样下一步无论是改路由、改前端还是只调整监控,都有可复查的依据。