try_files 的匹配机制是文件系统存在性检查加内部重定向,不改变 location 选择结果;按从左到右顺序检查每个参数对应的真实路径,首个存在即返回,最后一个参数为兜底动作(/开头触发内部重定向、@开头跳命名location、=404等直接返回状态码)。

try_files 的匹配机制不是 location 匹配,而是文件系统存在性检查 + 内部重定向,它在 location 块内部执行,不改变 location 选择结果。
检查顺序严格从左到右
try_files 后面的参数(除最后一个外)按书写顺序依次检查:
- 每个参数先拼接 root 或 alias 路径,生成真实文件系统路径
- $uri 对应找文件,$uri/ 对应找目录(需目录内有 index 指令定义的默认文件才视为“存在”)
- 遇到第一个存在的文件或可服务的目录,立即返回该资源,不再往后检查
- 整个过程不触发外部跳转,客户端无感知
最后一个参数是兜底动作,不是文件路径
它不参与磁盘检查,只起控制作用:
- 以 / 开头(如 /index.html):发起内部重定向,Nginx 重新用新 URI 匹配 location
- @ 开头(如 @php):直接跳入命名 location,绕过 location 匹配流程
- =404 或 =403:直接返回对应状态码,不进任何 location
- 不能写成 http:// 或 proxy_pass 地址——那是 proxy_pass 的职责
它不替代 location 匹配,也不影响匹配优先级
try_files 在 location 已被选定后才执行:
- 比如请求 /abc.php,先由 Nginx 按照 location ~ \.php$ 规则匹配到 PHP 处理块,再执行其中的 try_files
- 若该块没配 try_files,而只在 location / 里配了,那对 .php 请求完全无效——根本进不到那个块
- 常见错误:在通用 location / 里配了 try_files $uri $uri/ /index.php,却忘了在 PHP location 块里也加 try_files $uri =404,导致不存在的 .php 文件直接报错而非回退
常见组合与行为示例
这些写法背后逻辑一致:
- SPA 配置:try_files $uri $uri/ /index.html → 找不到静态资源时,内部重定向到 /index.html,由前端路由接管
- 动静分离兜底:try_files $uri $uri/ @backend → 未命中静态资源,跳命名 location,那里写 proxy_pass
- 多级缓存查找:try_files /cache$uri /origin$uri =404 → 先查缓存路径,再查原始路径,都失败就 404
- 带参数保留的重定向:try_files $uri $uri/ /index.php?$args → 注意 $args 显式拼接,否则内部重定向会丢失查询参数











