$uri 不含查询参数,因它是 Nginx 解码后的路径部分,严格排除 ? 后内容;try_files 仅基于 $uri 检查文件或目录,参数始终透传至最终资源。

带查询参数(如 /user?id=123)的请求,try_files 本身**不处理、也不影响**参数部分——它只检查 $uri(即问号 ? 之前的部分),参数始终被原样保留并透传到最终返回的资源或后续处理中。
为什么 $uri 不含参数
$uri 是 Nginx 内置变量,定义为“解码后的请求路径”,严格排除查询字符串。例如:
- 请求
/api/data?sort=asc&page=2→$uri值为/api/data - 请求
/about#contact(锚点)→$uri仍为/about(锚点由浏览器处理,不发往服务端)
因此 try_files $uri $uri/ /index.html 实际检查的是 /api/data 文件是否存在,再查 /api/data/ 目录,最后回退到 /index.html —— 而 ?sort=asc&page=2 会完整附在 /index.html 响应上(浏览器收到的是 /index.html?sort=asc&page=2)。
常见回退场景中的实际表现
多数情况下这是期望行为,尤其对 SPA:
- 前端路由
/dashboard?tab=logs→$uri = /dashboard不存在静态文件 → 回退至/index.html→ 浏览器加载后,JS 读取location.search解析参数,跳转对应视图 - 真实 API 请求
/static/config.json?v=2.1.0→$uri = /static/config.json存在 → 直接返回该文件,?v=2.1.0仅用于缓存 busting,不影响服务逻辑
需要干预参数时的处理方式
如果业务要求根据参数做不同回退(如 ?mode=preview 强制走某个模板),try_files 无法直接实现——它不解析 $args。此时需配合其他指令:
- 用
if ($args ~ "mode=preview") { rewrite ^(.*)$ /preview.html? break; }提前分流(注意:仅限简单判断,避免复杂逻辑) - 将参数提取为变量,在命名 location 中统一处理:
location @backend {<br> fastcgi_param QUERY_STRING $query_string;<br> include fastcgi_params;<br> fastcgi_pass php-fpm;<br> }
这样后端(如 PHP)能完整拿到原始参数继续处理
特别注意 fallback 路径里的参数继承
当回退目标是带斜杠的 URI(如 /index.php),Nginx 默认把原始 $args 自动拼上去:
请求 /user/5?format=json → try_files $uri /index.php → 实际转发为 /index.php?format=json
若不希望透传,显式清空:try_files $uri /index.php?(结尾问号表示丢弃原始参数)


















