三个变量各自是什么?
在Nginx重定向和rewrite配置中,$is_args、$args、$request_uri 这三个变量几乎每次都要用到,但很多人分不清它们的区别,导致重定向后查询参数丢失、URL拼接出错等问题。本文用实际例子把这三个变量讲清楚,让你再也不踩坑。
$request_uri:完整的原始请求URI(含参数)
$request_uri 是Nginx内置变量,表示客户端发来的原始请求URI,包含问号及后面的全部查询参数,并且不会被rewrite指令修改。
举例:用户访问 /search?q=nginx&page=2,则:
$request_uri=/search?q=nginx&page=2
关键特性:
- 只读变量,任何rewrite操作都不会改变它的值
- 包含完整的查询字符串(含问号)
- 最适合用在
return 301 https://example.com$request_uri;这种需要完整保留原始请求的场景
$args:查询参数部分(不含问号)
$args 表示URI中的查询参数部分,不含前面的问号。它与 $query_string 是完全等价的变量。
同上例 /search?q=nginx&page=2:
$args=q=nginx&page=2
关键特性:
- 可读可写,可以在配置中用
set或直接修改 - 不含问号,需要手动拼接
?或配合$is_args使用 - 适合需要提取、修改、重新组装查询参数的场景
$is_args:智能问号
$is_args 的值取决于当前请求是否带有查询参数:
- 有参数时,值为
? - 无参数时,值为空字符串
""
它的唯一作用就是在拼接URL时自动决定是否加问号,避免你手写条件判断。
举例:
/search?q=nginx→$is_args=?/search→$is_args=""
三个变量对比一览表
| 变量 | 含义 | 含问号? | 可修改? | 典型用途 |
|---|---|---|---|---|
$request_uri | 完整原始URI(含参数) | 是 | 否(只读) | return重定向,完整保留请求 |
$args | 查询参数(不含?) | 否 | 是 | 提取、修改查询参数 |
$is_args | 有参数时为"?",否则为空 | — | 否 | 拼接URL时自动判断是否加? |
重定向场景中的正确用法
场景1:HTTP跳转HTTPS,完整保留参数
server {
listen 80;
server_name www.youres.cn;
# 用 $request_uri 原封不动保留完整URI和参数
return 301 https://www.youres.cn$request_uri;
}
这是最推荐写法。$request_uri 只读且完整,不会因为任何rewrite规则而改变,保证参数不丢失。
场景2:rewrite中重新组装目标URL
# 旧路径重定向到新路径,同时保留原有查询参数 rewrite ^/old-page$ /new-page$is_args$args? last;
$is_args$args 组合会自动处理"有没有参数"的两种情况,不用手写if判断,是最规范的写法。
场景3:手动拼接时只用$args(容易出错)
# 错误写法:无参数时末尾会多出一个多余的 ? rewrite ^/old(.*)$ /new$1?$args? last;
当原请求没有查询参数时,$args 为空,结果是 /new-path?,末尾多了一个无意义的问号,虽然通常不影响访问,但不规范。
常见错误写法
错误1:return中只用 $uri,导致参数全部丢失
# 错误:参数会丢失 return 301 https://www.youres.cn$uri;
$uri 不含查询参数,正确写法是用 $request_uri 代替。
错误2:rewrite替换字符串末尾手写问号
# 容易出问题 rewrite ^/old$ /new?$args? last; # 正确写法 rewrite ^/old$ /new$is_args$args? last;
错误3:混淆 $request_uri 和 $uri
$uri 是Nginx经过标准化处理后的URI(不含参数,且内部重定向后会改变),而 $request_uri 始终是客户端发来的原始请求。两者不能互换,尤其在重定向场景中。
实战配置示例
以下是一个完整的HTTP强制跳转HTTPS配置,正确处理参数保留:
server {
listen 80;
server_name www.youres.cn youres.cn;
# 同时支持带路径和带参数的请求
return 301 https://www.youres.cn$request_uri;
}
server {
listen 443 ssl;
server_name www.youres.cn;
# ... SSL配置 ...
# 将不含www的域名也跳转过来,同样保留参数
if ($host != 'www.youres.cn') {
return 301 https://www.youres.cn$request_uri;
}
}
相关文章
总结
记住这三句话就够了:
$request_uri:原始完整URI,只读,return重定向首选$args:纯参数部分(不含?),可修改,适合加工参数的场景$is_args:智能问号,拼接URL时自动判断是否加?
掌握这三个变量的区别,Nginx重定向配置中的参数丢失问题就解决了一大半。
版权声明
本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论