在 Linux 主机上把 WordPress 迁移到大小写不敏感的开发环境、或反过来把本地 Windows 站点上线到 Linux 主机时,最常见的问题不是文件丢失,而是同一张图片、同一个 CSS 文件在数据库里被写成 Logo.PNG,磁盘上却是 logo.png。结论是有条件的:如果主机是大小写敏感的 Linux 文件系统,而数据库、主题模板或页面构建器里混用了大小写,那么统一映射只能靠“先定位真实文件名,再改引用”,不能靠主机层面强制忽略大小写来兜底。缺少完整日志或服务器权限时,仍可执行一个最小动作:用一次全站抓取记录所有 404 的资源路径,再和实际目录做比对,这能确认问题是否集中在大小写,但抓取结果本身不能证明所有缺失资源都源于大小写,因为缓存、CDN 回源失败或文件确实未上传也会产生同样的 404。
有些运维会建议在 Linux 上挂载大小写不敏感的文件系统,或给 Nginx 加正则重写来匹配任意大小写。这在单一站点、文件数量少时可以临时缓解,但会带来两个代价。第一,重写规则很难覆盖带查询串的静态资源、带版本号的 ?ver= 参数,以及通过 PHP 动态读取的文件路径。第二,一旦规则写得过宽,可能把本应 404 的请求也指向某个同名文件,掩盖真正的问题。
更稳妥的判断是:大小写差异属于“数据与磁盘不一致”,修复点应该在引用方,而不是在文件系统。主机只负责按你给出的路径去找文件,路径错了,主机没有义务猜测你的意图。
这是最典型的情况。表现是页面正常,但图片、字体或某个 CSS 返回 404。判断依据:把 404 的 URL 路径与服务器上 ls 列出的真实文件名逐字对比,只有字母大小写不同。处理动作是改数据库或模板中的引用,而不是改文件名。改文件名的风险在于,同一个文件可能被多处用不同大小写引用,改文件名会让原本正确的那一处也断掉。
某些上传流程会把大写字母转成小写,或把空格转成连字符。这时磁盘上的文件已经变了,但数据库里仍记录原始名称。判断依据是媒体库中显示的 URL 与服务器实际文件名不一致。处理动作是更新数据库中的附件元数据,并同步修正文章正文里的硬编码路径。
开发机是 macOS,生产是 Linux,同一份代码在两处表现不同。判断依据是同一路径在开发环境能访问、在生产返回 404。处理动作是在上线前把引用统一为小写,并把这条规则写进部署检查项,而不是每次上线后手动补。
如果你拿不到数据库写权限,也没有服务器 shell,仍可以按下面的顺序做一次可验证的排查。假设站点有可访问的前台页面,且你能导出或查看页面 HTML。
这个动作的结果会直接影响下一步:如果清单很短且集中在少数目录,可以逐条手工修正;如果清单很长且分散,说明引用来源可能是主题、插件或页面构建器的导出数据,需要先找到生成这些路径的那一层,否则改完一处还会再出现。
假设你确认了某个图片 Hero.JPG 在磁盘上是 hero.jpg,于是把所有引用改成小写。改完后页面仍然 404。此时“大小写是唯一原因”的结论失效。合理解释至少还有:该文件位于一个被 .htaccess 或 Nginx 规则限制访问的目录;文件权限是 600,Web 进程读不到;或者 CDN 缓存了旧的 404 响应,回源请求根本没到主机。这些情况下,继续改大小写不会有效果,应该先检查响应头和缓存状态,再决定是否清缓存或调整权限。
另一个反例是:主机本身运行在大小写不敏感的文件系统上(例如某些容器镜像的特定挂载方式)。此时大小写写错也能访问,问题被隐藏,直到迁移到另一台敏感主机才暴露。所以“当前能访问”不能证明引用的大小写是正确的。
统一映射的长期做法是约定一条规则并让它可检查:所有上传文件名、模板中引用的静态资源路径、数据库里存储的附件路径,一律使用小写字母加连字符。可以写一个简单的检查脚本,在部署前扫描主题和插件目录中的硬编码路径,输出含大写字母的引用清单。这个脚本不需要服务器权限,在本地代码库就能跑。
需要提醒的是,这类检查只能发现代码里的引用,发现不了数据库内容里的路径,也发现不了通过页面构建器动态生成的 URL。因此它适合作为部署前的一道过滤,不能替代对线上 404 的实际观测。把两者结合,才能在下一次迁移或换主机时,让路径大小写不再成为反复出现的问题。