Nginx 文件存在却返回 404:root、alias 与路径匹配排查
Nginx 返回 404 时,先问“它实际去哪个目录找了哪个文件”。你在终端看到文件存在,只证明某个路径有文件,不证明请求使用了相同的站点和路径映射。本文适用于常见 Linux Nginx 静态站点,示例目录需要替换成自己的实际部署位置。
先证明请求命中了正确站点
核对域名解析、访问端口和 server_name,再查看目标站点的访问日志。直接通过 IP 打开网站时,可能进入默认站点;通过域名访问时,也可能因重复配置而匹配到另一块。先确认日志落在哪个文件,再读该站点的有效配置。
本地可以带上真实域名请求头测试 HTTP 入口;HTTPS 则还要保留正确域名参与证书与 SNI 选择。若本地测试正确而公网失败,继续查 CDN 回源、旧解析或多节点部署,而不是在本机无休止地移动文件。Nginx 请求处理顺序
root 是把请求路径接在目录后面
假设站点设置如下:
location /assets/ {
root /srv/site/public;
try_files $uri =404;
}
请求 /assets/logo.png 对应的文件是 /srv/site/public/assets/logo.png,并不是 /srv/site/public/logo.png。排查时把完整 URL 路径和 root 目录写在纸上拼接,比盲目调整配置更容易发现重复或缺失的一层目录。
检查发布脚本是否把文件放进了额外的 dist 或 public 子目录,文件名大小写是否一致。Linux 常见文件系统区分大小写,本地开发电脑能打开的资源地址,放到服务器上可能不再匹配。
alias 用于替换匹配的路径前缀
如果磁盘上只有 /srv/shared-images/logo.png,希望通过 /images/logo.png 提供,可以明确使用目录别名:
location /images/ {
alias /srv/shared-images/;
}
目录型 location 与 alias 的末尾斜杠需要配对理解。这里 /images/ 被替换为指定磁盘目录,剩余文件名接在其后。不要把 root 与 alias 当成可以随意互换的写法;正则 location 中的 alias 还有不同要求,简单目录映射优先保持清晰。Nginx 核心模块文档
别名目录应只包含允许公开的资源,不能直接指向备份、配置或密钥目录。修好 404 的同时,也要检查相邻文件是否被意外开放下载。
权限与应用回退分开检查
目标文件需要能被 Nginx 工作进程读取,上层目录需要允许穿越。查看错误日志区分文件不存在与权限问题,而不是只看浏览器上的最终状态。应用或自定义错误页可能把底层问题统一包装成 404,因此还需要对照实际处理链。
try_files 最后的处理方式会改变排查结果。单页应用可能把页面路由回退到入口 HTML,但丢失的脚本、样式与图片应保持明确的失败状态。若任何地址都返回首页,监控看似正常,浏览器却可能把 HTML 当脚本解析。
先测试一个存在资源、一个不存在资源和一个应用路由,确认三者分别走预期处理方式。不要用“所有路径回首页”作为通用修复,否则会掩盖发布漏文件和链接错误。
改一处映射,验证一组路径
备份本次站点文件,修改后执行 sudo nginx -t,通过后再重新加载。测试目录首页、带子目录文件、大小写错误路径和不存在文件,并检查返回内容类型。只确认 HTTP 200 不够,下载到的内容必须是预期文件。
若变化影响已有资源,恢复原配置并重新加载,不要同时改磁盘位置和多条重写规则。记录请求路径到文件路径的映射,交给负责构建与上传的人一起核对。后续发布目录结构改变时,先更新这份映射和样本,再安排上线。