try_files 是 Nginx 按序检查文件或目录存在性并内部重写至最后 URI 的指令,用于静态服务、SPA 路由回退及 PHP 回退等场景,必须置于 location 块内,末参数须为合法 URI 且不支持动态变量拼接。

try_files 是 Nginx 中用于按顺序检查文件或路径是否存在,并在前一个不存在时尝试下一个的核心指令。它常用于静态资源服务、单页应用(SPA)的前端路由回退(如 Vue/React 的 history 模式),以及避免后端不必要的请求。
基本语法与执行逻辑
语法格式为:
try_files file1 file2 ... uri;含义是:Nginx 依次检查 file1、file2 是否作为真实文件或目录存在(注意:目录需以 / 结尾才被识别);若都不存在,则内部重写请求到最后的 uri(可以是命名 location、普通路径,或带参数的 URI)。
关键点:
- 每个
file都相对于root或alias指令定义的根路径 - 最后一个参数必须是 URI(不能是文件路径),且不支持变量(如
$uri可用,但$arg_x等动态变量不可直接拼接) - 一旦匹配到文件或目录,Nginx 直接返回该资源,不再执行后续 location 块中的其他指令(如 proxy_pass)
常见用法示例
1. 静态资源兜底 + PHP 后端回退
适用于传统 PHP 站点,优先服务静态文件(.html、.css、.js),找不到再交给 PHP-FPM 处理:
root /var/www/site;
try_files $uri $uri/ /index.php?$query_string;
}
说明:
– $uri 匹配精确文件(如 /style.css)
– $uri/ 匹配同名目录(如请求 /blog/ 且存在该目录)
– 最后回退到 /index.php,并透传查询参数
2. SPA 前端路由回退(History 模式)
Vue Router 或 React Router 使用 history 模式时,刷新 /user/123 会 404,需将所有非静态资源请求指向 index.html:
root /var/www/app;
try_files $uri $uri/ /index.html;
}
注意:确保 /index.html 在 root 目录下存在,且不要漏掉 $uri/(否则访问子目录会 403 或 404)
配合命名 location 实现复杂回退
当需要更精细控制(比如区分 API 和页面),可结合 @named_location:
root /var/www/frontend;
try_files $uri $uri/ @backend;
}
location /api/ {
proxy_pass http://backend;
}
location @backend {
proxy_pass http://backend;
proxy_set_header Host $host;
}
这样,所有非静态资源请求(包括根路径和深层前端路由)都会进入 @backend,而 /api/ 路径仍走独立代理规则。
注意事项与易错点
-
try_files必须放在location块内,不能在 server 级直接使用 -
$uri是解码后的路径,不包含查询字符串;要用$request_uri保留原始 URI(含参数),但注意它不能用于文件检查(因为含 ?) - 如果误写成
try_files $uri /index.php(无$query_string),PHP 脚本将收不到 GET 参数 - 使用
alias时,$uri的匹配行为与root不同,需特别验证路径拼接是否正确


















