Nginx 的 server 块通过 server_name 指令按正则、通配符(前导优先)、精确匹配三级顺序匹配 Host 头,泛域名需 DNS 泛解析、对应 SSL 证书且无更高优先级 server 块干扰,正则可捕获子域名用于动态路由,常见失效原因包括 listen 冲突、Host 头缺失、未重载配置及浏览器缓存。

server 块本身不解析域名,它只匹配请求中 Host 头的值。所谓“泛域名匹配”,是靠 server_name 指令配合通配符或正则表达式,实现对一类子域名的统一识别与路由。
server_name 的三种匹配方式及优先级
Nginx 对 Host 头的匹配有明确顺序,不是并行判断:
- 先尝试正则匹配(以
~或~*开头),匹配成功即用,且支持捕获变量(如~^(?<sub>.+)\.example\.com$</sub>中的$sub) - 再找通配符匹配:前导通配符(
*.example.com)优先于后缀通配符(example.*),且只支持单层(*.example.com匹配api.example.com,但不匹配dev.api.example.com) - 最后 fallback 到精确匹配(如
server_name example.com www.example.com;),多个值用空格分隔
泛域名实际生效的前提条件
仅配置 server_name *.example.com; 是不够的,还需确保:
- DNS 已设置泛解析(即所有
*.example.com子域名均指向该 Nginx 服务器 IP) - 若走 HTTPS,SSL 证书必须覆盖泛域名(如使用
*.example.com证书,注意不含根域名;如需同时支持example.com,应选多域名证书或 SAN 证书) - 没有更高优先级的 server 块“抢走”请求——比如某个精确匹配
app.example.com的 server 块,会优先生效,导致泛匹配失效
用正则实现动态子域名路由
当需要把不同子域名映射到不同后端或路径时,正则匹配最灵活:
- 写法示例:
server_name ~^(?<domain>[a-z0-9\-]+)\.example\.com$;</domain> - 可直接在
proxy_pass或root中引用捕获组:proxy_pass http://backend-$domain/;或root /var/www/$domain; - 注意转义点号(
\.)和限制字符集(避免注入风险),建议用[a-z0-9\-]+而非.+
常见误配与排查要点
泛匹配不起作用,多数源于底层逻辑被忽略:
- listen 配置冲突:如果两个 server 块都监听
80且无default_server,Nginx 可能随机选一个,导致泛匹配块未被触发 - Host 头为空或非法:某些客户端或代理可能不带 Host 头,此时 Nginx 会退至 default server,而非泛匹配块
- 配置未重载:修改
server_name后必须执行nginx -t && nginx -s reload,否则变更不生效 - 浏览器缓存 301:测试时若之前设过跳转,记得清缓存或用
curl -H "Host: test.example.com" http://your-ip绕过 DNS 和缓存


















