nginx中泛域名(如.example.com)匹配优先级天然低于精确域名,匹配顺序为:完全匹配 > 通配符(开头)> 通配符(*结尾)> 正则 > 默认server;需用nginx -t确认生效配置并添加响应头验证实际匹配块。

在 Nginx 中,泛域名(如 *.example.com)的匹配优先级**天然低于精确域名**(如 www.example.com),这是 Nginx 的设计规则,不是配置错误。排查的关键是确认当前请求是否真的命中了预期的 server 块,以及是否因优先级、语法或顺序问题导致行为不符合预期。
确认 Nginx 的 server_name 匹配逻辑
Nginx 选择 server 块的顺序严格遵循以下优先级(从高到低):
- 完全匹配的
server_name(如server_name api.example.com;) - 以
*开头的最长通配符(如server_name *.example.com;) - 以
*结尾的最长通配符(如server_name example.*;) - 正则表达式(按配置文件中出现顺序,第一个匹配的生效)
- 默认 server(含
default_server标志或第一个 listen 的 server)
注意:*.example.com 不匹配 example.com(无子域),也不匹配 foo.bar.example.com(仅匹配一级子域)。若需覆盖根域,需显式声明 example.com 或用正则。
检查配置中是否存在更高优先级的精确匹配
常见误判来源:你以为请求进了泛域名块,实际被另一个更早定义、且恰好匹配的精确域名 block 拦截了。
- 用
nginx -t验证语法,再执行nginx -T(大写 T)输出**全部生效配置**,搜索相关域名,确认各server_name的定义顺序和内容 - 特别检查是否有遗漏的
server_name example.com、www.example.com或拼写一致的别名 - 确保没有其他 include 文件(如
sites-enabled/*)悄悄加载了冲突配置
验证实际匹配结果(最可靠方式)
在疑似生效的 server 块中临时添加唯一标识,观察响应头:
server {
server_name *.example.com;
location / {
add_header X-Server "wildcard";
# 其他配置...
}
}
同时,在精确域名块中加不同标识:
server {
server_name www.example.com;
location / {
add_header X-Server "exact-www";
# ...
}
}
然后用 curl -I http://www.example.com/ 查看响应头中的 X-Server,直接确认哪个 server 块真正处理了请求。
泛域名无法覆盖根域?补上显式声明
如果希望 example.com 和 www.example.com 都走同一套逻辑,但又不想重复配置,可合并声明:
server {
server_name example.com www.example.com *.example.com;
# 注意:顺序不影响优先级,Nginx 内部仍按精确 > 泛域名规则匹配
# 但这样写便于维护,且确保根域和常用子域都被覆盖
}
或者使用正则(需谨慎):
server {
server_name ~^(?<subdomain>.+\.)?example\.com$;
# $subdomain 可用于后续 rewrite 或变量判断
}</subdomain>
不复杂但容易忽略:优先级是硬编码规则,不能通过调整配置顺序改变泛域名与精确域名的相对权重。排查核心就是——看清实际生效的是哪个 block,而不是假设它该进哪个 block。











