try_files核心是“从左到右、一命中就停”,非末尾参数按序拼接root路径检查文件或目录存在性,末尾参数为内部重定向目标(/path或@named),不参与检查。

try_files 的核心就是“从左到右、一命中就停”。它不跳过、不回溯,只要某一项在文件系统中真实存在(且可读),Nginx 就立即用它响应请求,后续参数完全不执行。
检查顺序严格按空格分隔的参数排列
每个非末尾参数都会被拼接到 root(或 alias)定义的根路径下,作为完整文件系统路径进行存在性判断:
- 先检查是不是普通文件:比如
$uri对应/var/www/app/js/main.js,存在则直接返回 - 不是文件,再检查是不是目录:比如
$uri/对应/var/www/app/about/,若该目录存在且含index.html(由index指令指定),就返回那个 index 文件 - 目录存在但没 index 文件?视为“不存在”,继续下一个参数
- 所有非末尾参数都失败,才触发最后一步——内部重写到末尾的 URI(如
/index.html)或跳转到命名 location(如@backend)
末尾参数是特殊角色,不参与存在性检查
最后一个参数不是用来“找文件”的,而是兜底动作的触发目标:
- 必须以
/开头(如/index.html)或以@开头(如@php),否则配置会报错 - 它不会被拼到 root 下检查是否存在,而是直接发起一次新的 location 匹配
- 例如
try_files $uri /static$uri /fallback.html;,即使/static$uri对应的路径根本不存在,只要它是倒数第二项,Nginx 仍会尝试拼接并检查;但最后一项/fallback.html是直接交由对应 location 处理
常见路径拼接细节不能错
$uri 值自带开头斜杠(如 /api/users),和 root /var/www; 拼接时是直接连接,不是追加:
- ✅ 正确:
root /var/www; try_files $uri /index.html;→ 检查/var/www/api/users和/var/www/index.html - ❌ 错误:
try_files $uri /$uri /index.html;→ 第二项变成/var/www//api/users,多一个//,基本找不到 - 目录请求要注意结尾斜杠:
GET /admin/时,$uri就是/admin/,$uri/会变成/admin//,通常应避免重复加斜杠
调试时可用两个变量验证实际路径
在 log_format 或 error_log 中加入:
-
$request_filename:Nginx 实际要打开的完整文件系统路径 -
$document_root:当前生效的 root 路径,帮你确认拼接基准是否正确
配合 access_log 或 error_log 输出,能快速定位“为什么没找到文件”——是路径拼错了,还是权限不对,还是根本没放对位置。











