0

Nginx $is_args $args $request_uri三个变量对比详解:搞懂它们,重定向再也不踩坑

2026.05.28 | youres | 16次围观

三个变量各自是什么?

在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;
    }
}

相关文章

总结

记住这三句话就够了:

  1. $request_uri:原始完整URI,只读,return重定向首选
  2. $args:纯参数部分(不含?),可修改,适合加工参数的场景
  3. $is_args:智能问号,拼接URL时自动判断是否加 ?

掌握这三个变量的区别,Nginx重定向配置中的参数丢失问题就解决了一大半。

版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论
882文章数 0评论数
作者其它文章