当 nginx 收到请求时,它会按照精确域名、带通配符前缀的域名、带通配符后缀的域名、以及正则表达式域名的优先级顺序进行匹配。如果存在冲突,nginx 会优先选择最长且最具体的匹配项,而不是简单地按配置文件中的书写顺序决定。

Nginx 匹配泛域名与精确域名的优先级规则是什么
Nginx 在处理 server_name 时,遵循严格的优先级排序:精确名称(如 example.com)优先级最高;其次是带有通配符前缀的名称(如 *.example.com);再次是带有通配符后缀的名称(如 example.*);最后是正则表达式名称(如 ~^www\d+\.example\.com$)。这意味着,如果同时配置了 example.com 和 *.example.com,针对 example.com 的请求将始终匹配精确域名块。

server {
listen 80;
server_name *.example.com;
root /var/www/subdomain;
}
server {
listen 80;
server_name example.com;
root /var/www/main;
}在上述配置中,访问 http://example.com 会进入第二个 server 块,因为精确匹配优先级高于通配符匹配。而访问 http://blog.example.com 则会进入第一个 server 块,因为它只符合通配符模式。这种机制确保了核心域名可以独立于子域名处理,无需依赖配置文件的物理顺序。
如何处理多个泛域名之间的冲突或重叠
当存在多个泛域名配置时,例如 *.example.com 和 dev.*,Nginx 同样依据最长匹配原则。如果请求的主机头是 dev.example.com,它既符合 *.example.com 也符合 dev.*。在这种情况下,Nginx 会比较匹配的长度,通常更具体的通配符组合会被优先选中,或者根据内部哈希表的查找结果确定。为了避免歧义,建议尽量避免重叠的泛域名定义,或者使用正则表达式明确指定特定子域名的行为。

server {
listen 80;
server_name dev.*;
root /var/www/dev;
}
server {
listen 80;
server_name *.example.com;
root /var/www/all-subdomains;
}在这个例子中,如果请求 dev.example.com,Nginx 可能会根据内部实现细节选择其中一个。为了安全起见,应将 dev.example.com 显式地定义为精确域名,或者在 dev.* 块中使用更具体的正则表达式。例如,使用 server_name ~^(?<subdomain>.+)\.example\.com$;</subdomain> 可以更灵活地控制子域名的路由逻辑,确保每个请求都能被唯一且正确地识别。
当请求的域名不匹配任何 server_name 时会发生什么
如果客户端请求的 Host 头无法匹配任何已配置的 server_name,Nginx 会将该请求路由到该监听端口(IP 和端口组合)下的默认服务器块。这个默认服务器块通常是配置文件中第一个出现的 server 块,除非通过 server_name _; 或 server_name default_server; 显式指定。因此,合理设置默认服务器块对于防止未授权访问或错误响应至关重要。


















