404 not found 的意思是服务器收到了请求,但找不到对应资源。当页面本来存在却返回 404,常见原因之一是配置互相冲突:重写规则、反向代理、路由、静态文件目录或大小写规则中,有两条以上规则对同一路径给出了不同处理结果。识别冲突的关键不是继续加规则,而是先确定哪条规则实际生效,再找出被覆盖或提前终止的那一条。
在动手改配置前,先排除简单情况。用 curl -I 请求出问题的 URL,观察状态码和响应头。如果返回 404,再直接请求服务器上的真实文件路径,例如把 /blog/post 换成 /blog/post/index.html。若真实路径能返回 200,而美化后的路径返回 404,问题更可能出在重写或路由层,而不是文件不存在。
判断依据可以归纳为:
请求进入服务器后通常要经过多个环节,每个环节都可能改写路径或直接返回响应。排查时按顺序检查,能快速定位冲突发生在哪一层。
/api 转发为 /api/api,后端自然找不到资源。rewrite、try_files、alias 等指令。多条规则命中同一路径时,先执行且带终止标记的规则会决定结果。一个可执行的验证方法:临时把可疑的重写规则改为返回固定内容或重定向到已知存在的页面。如果状态码随之改变,说明这条规则确实参与了该路径的处理;如果毫无变化,说明它没有生效或被更早的规则拦截。
当配置较多时,逐条阅读效率低。更有效的做法是做对比测试:复制一份配置,只保留与目标路径相关的规则,其余全部注释,然后重启或重载服务并再次请求。若 404 消失,再把注释掉的规则分批恢复,直到 404 重新出现,最后恢复的那一批里就包含冲突项。
适用条件是你能控制配置并可以安全重载。对于线上环境,应先在本地或预发布环境验证,避免直接改动生产配置。判断结果时注意:恢复某条规则后 404 重现,只能说明这条规则与问题相关,还需要确认它是覆盖了正确规则,还是与另一条规则组合后产生了错误路径。
有些冲突不在主配置文件中,而来自被包含的片段、环境变量或默认规则。常见来源包括:
针对缓存因素,可以在请求中加入随机查询参数或临时绕过缓存层再测试。如果绕过缓存后返回 200,说明配置可能已经正确,只是旧响应还在被复用。
配置冲突解决后,应看到这些信号:目标 URL 稳定返回 200;带斜杠与不带斜杠的版本行为一致且符合预期;大小写变体按既定规则处理;代理转发后的路径与后端路由完全匹配;日志中不再出现因路径改写导致的 404 记录。需要说明的是,robots.txt 的抓取限制不等于可靠的索引移除,站点地图也不保证收录,这些与 404 配置冲突是不同层面的问题,不要混在一起判断。
下一步:挑一个当前返回 404 的真实 URL,用 curl -I 记录状态码,再按“代理—重写—路由—静态目录”的顺序逐层注释规则做对比测试,直到定位到具体冲突项。