先给结论:当服务器或应用把 /Product/A 和 /product/a 当成两个不同资源时,单靠把其中一个地址做永久重定向并不能解决全部问题。你需要先确认大小写敏感发生在哪一层,再把所有等价写法收敛到一个规范形式,否则重定向只会把问题从一个入口搬到另一个入口。
把读者手里的页面或资料当作调查对象,按以下顺序检查,不要跳步。
这里的判断依据不是“哪个地址能打开”,而是“同一资源是否被系统视为多个标识”。如果两种写法都能返回 200,且内容相同,说明存在重复入口;如果只有一种返回 200,说明需要把另一种写法映射过去,而不是简单删除。
统一映射的核心是选一个规范形式,并让所有等价写法都指向它。选择时考虑三个条件:
/A-B 与 /a-b 同时存在且内容不同,此时不能简单转小写。假设一个资料库中同时存在 /Docs/Guide 和 /docs/guide,且两者内容一致。若外部引用以大写为主,可以把大写形式定为规范地址,把小写形式永久重定向过去;反过来也可以。关键是只选一个,并让服务器、应用路由和缓存键都按同一规则处理。
确定规范形式后,在请求最早到达的位置做映射,通常比在应用内部逐条判断更稳定。下面是一个假设的 Nginx 配置片段,用于把大写路径统一转为小写后再重定向:
location ~ [A-Z] { rewrite ^(.*)$ /${lowercase:$1} permanent; }
这个动作的结果是:所有含大写字母的请求先被转为小写,再返回 301。下一步要验证的是,转换后的小写地址是否真实存在且返回 200;如果不存在,说明规范形式选错了,或者资源本身没有对应的小写版本。此时应回到上一步重新选择规范形式,而不是继续叠加更多重定向规则。
如果使用应用层路由,同样要在路由匹配前做规范化,并确保规范化后的路径参与缓存键计算。否则即使浏览器地址统一了,缓存层仍可能保留两套副本。
规则上线后,用一组对照请求验证,而不是只看首页。
Location 指向规范形式。如果某个地址仍然返回 200 而不是 301,说明该请求没有经过你设置的重定向入口,可能被更具体的规则、静态文件直出或缓存命中拦截。这时应检查规则优先级和缓存键,而不是重复添加同一条重定向。
大小写统一映射还要注意几类情况。第一,查询字符串和片段标识符不参与路径大小写转换,不要误改。第二,如果路径中包含经过编码的字符,先解码再判断大小写,避免把编码后的字母误判为普通字符。第三,永久重定向会被客户端和中间缓存长期保存,规则错误时清理成本较高,因此建议先用 302 验证,确认无误后再改为 301。
另外,robots.txt 中的抓取限制不等于可靠的索引移除,站点地图也不保证收录。大小写映射解决的是访问入口收敛问题,不应把它当作索引控制的替代手段。不同搜索引擎对重定向和规范化的支持情况需要分别核查,不能假设一套规则在所有渠道表现一致。
最后,把这次统一映射的结果记录下来:规范形式是什么、在哪一层实现、哪些地址会跳转、验证时用了哪些对照请求。这样下一次出现类似路径差异时,可以直接判断是规则遗漏还是新的入口被引入,而不必从零排查。