404 not found 的字面含义是服务器收到了请求,但在它查找的路径上找不到对应资源。当同一批文件在本地能打开、上线后却间歇性 404,且日志里出现的是大小写不同的路径时,问题通常不在“文件丢了”,而在请求路径与实际存储路径没有统一映射。处理这类问题有两条主线:把映射规则收敛到一层去改写,或者让存储层对大小写不敏感。选哪条,取决于你的服务器类型、文件规模,以及能否接受一次性的路径迁移成本。
大小写引发的 404 往往有两种成因,表现相似但证据不同。
/Images/Logo.png,磁盘上是 /images/logo.png。Linux 文件系统区分大小写,查找直接失败,返回 404。这类问题的特征是:日志中 404 的 URL 大小写固定,且把该 URL 手动改成另一种大小写就能正常访问。区分两者的证据很直接:拿一条 404 的 URL,逐层比对“浏览器发出的路径”和“最终落到磁盘上的路径”。如果两者只差大小写,属于第一种;如果两者结构都不同,属于第二种。这个比对动作决定了后面该改链接、改规则,还是改存储。
做法是在请求进入应用或 Web 服务器时,把路径按固定规则归一化,比如全部转小写,再去匹配实际文件。适用于文件数量大、磁盘上大小写混杂、不方便逐个重命名的情况。
代价是必须保证归一化后的路径确实存在。假设磁盘上同时存在 /Images/a.png 和 /images/A.png,全部转小写后两者会撞到同一个目标,其中一个必然 404 或互相覆盖。所以在启用归一化前,要先检查是否存在“仅大小写不同”的重名文件。这个检查动作的结果会直接决定下一步:没有重名,可以放心归一化;存在重名,就必须先解决冲突,否则归一化只会把问题从“找不到”变成“找错”。
另一条路是让文件系统或对象存储对大小写不敏感,这样 /Images/Logo.png 和 /images/logo.png 指向同一资源。适用于你能控制存储层、且希望长期不再处理这类问题的情况。
代价是迁移和兼容成本。把区分大小写的存储换成不敏感方案,通常涉及数据迁移、挂载方式调整,以及验证原有依赖精确大小写的程序是否受影响。如果站点同时挂载了多个存储卷,还要确认所有卷的行为一致,否则会出现“部分路径能访问、部分不能”的混合状态。判断是否值得走这条路,可以看一个信号:如果 404 长期反复出现、且每次都要人工补链接,说明映射层归一化只是在打补丁,存储层统一才是收敛点。
假设某站有约两千个静态资源,日志显示每天有几十条 404,URL 里目录名首字母大写、文件名小写,而磁盘上目录名是小写。按上面的方法逐层比对,发现浏览器发出的路径与磁盘路径只差目录名的大小写,属于第一种成因。
此时先做重名检查:如果磁盘上不存在仅大小写不同的重名文件,可以在映射层加一条“目录名转小写”的规则,观察一段时间后 404 是否减少。若减少,说明归一化方向正确,后续可把规则扩展到文件名;若没有明显变化,说明还有别的层在改写路径,需要回到逐层比对,检查 CDN 或应用路由。这个动作的价值在于:它把“猜哪里出错”变成“用一次改动验证一种解释”,避免同时改多个层导致无法归因。
映射统一不等于问题彻底消失。返回 404 的 URL 如果曾经被访问过,搜索引擎可能仍保留旧记录,具体表现需要在对应搜索引擎中分别核查,不同引擎对失效 URL 的处理并不一致。用 robots.txt 限制抓取,并不等于可靠的索引移除;提交站点地图也不保证收录。这些手段各有边界,不能替代对映射本身的修复。
另外,如果站点启用了 HTTPS,它只解决传输加密,不保证没有漏洞,也不直接决定排名,与路径大小写问题无关,不要把它当作排查方向。真正要盯住的,是请求路径、映射规则、存储路径这三者是否指向同一个资源。三者对齐之后,404 才会从“反复出现”变成“可解释的个例”。