nginx rewrite指令支持直接引用内置变量(如$host、$uri、$args)拼接重写目标,需注意作用域、url编码安全及$uri与$request_uri的区别:前者解码规范化、适合内部重写,后者保留原始含参uri、适合跳转;含特殊字符时必须用双引号包裹replacement,避免解析错误。

Nginx 的 rewrite 指令支持直接使用内置变量(如 $host、$uri、$args 等)拼接重写目标,但要注意变量作用域和 URL 编码安全。
变量可在 rewrite 目标中直接拼接
Nginx 允许在 rewrite 的 replacement 部分直接引用变量,无需额外语法。例如:
-
rewrite ^/old/(.*)$ https://$host/new/$1 permanent;—— 保留当前域名,重写路径 -
rewrite ^/api/(.*)$ /v2/api/$1 break;—— 不跨域,仅内部路径替换 -
rewrite ^/blog/(.*)$ https://blog.$host/$1?ref=nginx redirect;—— 动态子域 + 附加查询参数
注意 $uri 和 $request_uri 的区别
$uri 是解码后、规范化后的路径(不含查询串,且已去除重复斜杠),适合用于内部重写;$request_uri 是原始请求 URI(含查询参数,未解码),更适合做外部跳转或日志记录。
- 用
$uri:重写到本地路径时更安全,避免双解码风险 - 用
$request_uri:跳转时保持原始参数不变,如rewrite ^/old(.*)$ https://example.com/new$1 permanent;
特殊字符需转义或用引号包裹
若目标路径含空格、$、{、} 等字符,必须用双引号包裹整个 replacement 字符串,否则 Nginx 会解析失败或截断:
- ✅ 正确:
rewrite ^/test$ "/new?host=$host&path=$uri" redirect; - ❌ 错误:
rewrite ^/test$ /new?host=$host&path=$uri redirect;(& 被 shell 解析,Nginx 配置报错)
避免循环重写与编码陷阱
使用变量拼接时,要防止因路径未标准化导致重复匹配:
- 加
^和$严格锚定匹配,减少误触发 - 慎用
$args拼接 —— 它不包含?,需手动添加,且原始参数可能含特殊字符,建议用$is_args$args组合:rewrite ^/old(.*)$ /new$1$is_args$args break; - 若目标含中文或特殊符号,Nginx 默认不自动编码,需确保上游能正确处理;必要时用
return 302替代rewrite ... redirect,配合escape(需 Lua 模块)或预处理











