最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Nginx 中 Rewrite 规则如何使用 set 指令在重写过程中自定义临时变量
时间:2026-08-23 20:03:48 编辑:袖梨 来源:一聚教程网
Nginx 的 set 指令用于在 server 或 location 块中定义请求级局部变量,仅当前请求有效,必须先声明后使用,值可为字符串、内置变量或正则捕获组,但不能在 rewrite 指令行内使用,且 if 中的 set 存在作用域限制;推荐用 map 替代 if+set 实现高效安全的条件映射。
Nginx 的 set 指令可以在 rewrite 过程中定义临时变量,但需注意它不能直接在 if 块或 rewrite 指令内部使用,而应放在 server 或 location 块顶层(或 if 内部)提前声明,再在后续 rewrite 中引用。
set 指令的基本用法和作用域限制
set 用于创建一个 NGINX 变量(以 $ 开头),值可以是字符串、其他变量、正则捕获组或内置变量。该变量仅在当前请求生命周期内有效,且只在当前作用域(如某个 location)及其子上下文中可用。
关键限制:
-
set不能出现在rewrite指令行里(语法错误) -
set在if块中定义时,只在该if分支内有效(NGINX 最新不推荐在if中大量使用set,因存在作用域陷阱) - 变量必须先定义后使用;未定义变量默认为空字符串,不会报错但可能导致重写逻辑异常
在 rewrite 前用 set 预设动态值
常见场景:根据 Host、URI 或请求头拼接目标路径。例如,把所有请求统一加前缀 /v1,但对特定域名跳过:
server {listen 80;server_name api.example.com internal.example.com;# 根据 host 设置标志变量set $version_prefix "";if ($host = "api.example.com") {set $version_prefix "/v1";}location / {# 使用预设的 $version_prefix 参与 rewriterewrite ^(.*)$ $version_prefix$1 break;}}
说明:这里 $version_prefix 在 if 中被赋值,随后在 rewrite 中拼接到原始 URI。注意 break 表示内部重写,不发起新请求。
结合正则捕获与 set 实现条件化重写
当需要从 URI 提取参数并参与后续判断时,可先用 set 保存捕获结果:
location /old/ {# 捕获旧路径中的模块名,存入变量if ($request_uri ~ ^/old/([^/]+)/) {set $module_name $1;}# 根据 module_name 跳转到不同新路径if ($module_name = "user") {rewrite ^/old/user/(.*)$ /api/v2/users/$1? permanent;}if ($module_name = "order") {rewrite ^/old/order/(.*)$ /api/v2/orders/$1? permanent;}}
⚠️ 注意:上述写法依赖 if + set,虽可行但属于 NGINX “不推荐但支持” 的模式。更健壮的方式是用 map 指令做映射(见下一条)。
推荐替代方案:用 map 替代 if + set 做变量映射
map 是更高效、更安全的变量生成方式,适合静态或简单规则映射,且在配置加载时编译,性能优于运行时 if:
map $host $api_prefix {default "";"api.example.com" "/v1";}map $uri $new_path { ~^/old/user/(.)/api/v2/users/$1; ~^/old/order/(.) /api/v2/orders/$1; default $uri; }
server { location /old/ { rewrite ^(.*)$ $new_path? permanent; } }
这样既避免了 if 嵌套问题,又让变量逻辑清晰可维护,还支持缓存优化。
相关文章
- 伽利略机器人首发“陆行具身系统”,打通轮车足底层技术壁垒 08-23
- 对于非计算机专业的人来说,学编程有意义吗? 08-23
- 给孩子讲讲AI:无数好答案都在等你的好问题 08-23
- 高中毕业后学编程有必要吗?别盲目学习... 08-23
- 机场休息室的抓拍肖像 08-23
- 小米路由器增强器怎么重置(小米路由器增强器重置方法) 08-23