结论先说:如果服务器、构建流程和链接生成器对大小写的处理不一致,统一映射应放在“请求进入应用之前”的一层完成,而不是靠内容编辑逐条改链接。可行的做法是让 Web 服务器或反向代理把已知的路径变体重定向到唯一规范地址,同时让构建阶段拒绝新增的大小写冲突。这个结论有前提:站点路径集合可枚举,且团队能接受一次以 301 为主的收敛期。若站点存在大量用户生成路径、或同一路径在不同大小写形式下确实对应不同资源,这条结论就不成立,强行统一映射会造成误伤。
同一事实在不同角色眼里往往不是一回事。开发认为“文件系统本来就不区分大小写”,编辑认为“链接写的是页面标题里的写法”,运维看到的是日志里一堆 404。要把它变成可核对的项目,先按来源分类:
/Images/A.jpg 与 /images/a.jpg 是两个文件;而开发在 Windows 或 macOS 默认卷上本地测试时,两者可能都能打开。差异在部署后才暴露。判断依据很简单:把同一路径的几种大小写变体分别请求一次,看响应是 200、301 还是 404,再对照服务器上实际存在的文件名。如果变体都能返回 200,说明系统在某处做了不透明的大小写折叠,问题被掩盖;如果部分 404,说明差异已经进入可被外部观察的状态。
映射位置有三个常见选择,适用条件不同:
一个假设的例子:某静态站点有 /Guide/Setup.html,模板里写成 /guide/setup.html。若在服务器层加一条把该变体 301 到规范地址的规则,外部请求会被收敛;下一步应检查构建输出里是否同时存在两个仅大小写不同的文件,若有,说明源目录本身已冲突,仅靠服务器规则只是掩盖。这个动作的结果会直接决定下一步是清理源文件,还是继续补规则。
最需要警惕的反例是:路径大小写不同确实对应不同内容。例如 API 端点 /User/Profile 与 /user/profile 在旧系统中被设计为不同资源,或图片文件名本身来自用户上传且区分大小写。此时任何“全部折叠为小写”的映射都会把两个合法资源合并成一个,属于破坏性操作。
另一个反例是路径集合无法枚举:带哈希、带时间戳或带用户 ID 的 URL 大量存在,逐条映射不可维护。这种情况下应改为在生成端约束,而不是在请求端兜底。
还需要注意,重定向规则本身可能被缓存。若映射规则上线后又修正,客户端和中间缓存仍可能持有旧的 301。因此规则上线前应先在测试环境验证,上线后观察一段时间再清理临时规则。
建议按以下顺序推进,每一步都产出可核对的结果:
如果团队对“哪个形式是规范”无法达成一致,就把这个分歧本身变成一个待决项:列出每种形式对应的现有引用数量、外部链接数量和构建产物情况,用这些可核对的事实做决定,而不是靠谁的声音大。规范一旦确定,映射规则和构建检查都应指向同一个形式,否则两处标准不一致会制造新的死链。