Nginx 中 server_name 本身不执行重定向,但可通过正则表达式(如 ~^(\w+).example.com$)捕获域名片段到 $1 等变量,再结合 return 或 rewrite 实现 301/302 跳转,推荐优先使用 return 指令以提升性能和可读性。

在 Nginx 中,server_name 本身不直接“执行”重定向,但它可以配合正则表达式捕获域名片段,再结合 rewrite 或 return 指令实现灵活的域名跳转。关键在于:用正则定义 server_name 捕获变量(如 $1、$2),再在后续指令中引用这些变量构造跳转逻辑。
用正则 server_name 捕获子域名或主域名
通过 ~ 开头的正则表达式配置 server_name,可使用括号 () 定义捕获组,匹配时自动赋值给 $1、$2 等变量:
-
server_name ~^([a-z0-9\-]+)\.example\.com$;→ 访问blog.example.com时,$1值为blog -
server_name ~^(?:www\.)?(.+)$;→ 访问example.com或www.example.com,$1都是example.com -
server_name ~^([^.]+)\.(.+)$;→ 匹配任意一级子域名,$1是前缀(如api),$2是主域(如example.com)
基于捕获结果做 301/302 重定向
捕获后,常用两种方式跳转,推荐优先用 return(更高效、语义清晰):
- 统一跳转到带 www 的版本:
server { listen 80; server_name ~^([^\.]+)\.example\.com$;<br> return 301 https://www.$1.example.com$request_uri;<br>} - 将所有非 www 请求重定向到 www:
server { listen 80; server_name ~^(?!www\.)(.+)$;<br> return 301 https://www.$1$request_uri;<br>} - 用 rewrite + permanent(等效于 return 301):
rewrite ^(.*)$ https://new-domain.com$1 permanent;(需确保在匹配的 server 块内)
配合 if 判断做条件跳转(慎用但有时必要)
虽然 if 在 location 外有性能和逻辑风险,但在 server 块中用于简单 Host 判断仍常见:
- 把裸域跳转到 www:
if ($host = "example.com") {<br> return 301 https://www.example.com$request_uri;<br>} - 根据捕获的子域名分流:
server_name ~^([a-z0-9\-]+)\.example\.com$;<br>if ($1 = "dev") {<br> return 302 https://staging.example.com$request_uri;<br>}
注意事项与避坑点
实际配置时要注意几个关键细节:
- 正则
server_name必须以~开头,否则会被当作字面量匹配 - 捕获变量(如
$1)只在当前 server 块内有效,不能跨 server 引用 -
return比rewrite ... permanent更轻量,无正则回溯开销,优先选return - 避免在 if 中使用复杂正则或嵌套判断;Nginx 官方建议尽量用
map指令替代大量 if - 测试时用
curl -I http://xxx查看响应头中的Location和状态码,确认是否符合预期











