在 nginx 中配置 ip 与域名混合解析,核心做法是在 server 块中同时使用 listen ... default_server 和 server_name。通过设置默认服务器处理未匹配域名的请求,并在其他虚拟主机中指定具体域名,即可实现基于 ip 访问和基于域名访问的共存。

如何区分 IP 直接访问和域名访问
区分的关键在于 default_server 参数和 server_name 的通配符或精确匹配。当用户通过 IP 地址访问时,Nginx 会寻找标记为 default_server 的块;当用户通过域名访问时,Nginx 会根据 server_name 进行匹配。

server {
listen 80 default_server;
server_name _;
root /var/www/ip_access;
}
server {
listen 80;
server_name example.com www.example.com;
root /var/www/domain_access;
}
上述配置中,第一个 server 块监听 80 端口并标记为默认服务器,其 server_name 设置为下划线 _,这是一个常见的占位符,用于捕获所有未明确匹配的请求,包括直接的 IP 访问。第二个 server 块则专门处理 example.com 及其子域名的请求。如果用户通过 http://192.168.1.1 访问,将进入第一个块;如果通过 http://example.com 访问,将进入第二个块。
如何处理非标准端口的混合解析
对于非标准端口(如 8080),同样可以使用 default_server 来区分。需要注意的是,每个端口只能有一个 default_server。如果在同一端口上配置了多个 server 块,只有标记为 default_server 的那个会作为 IP 访问的兜底方案。

server {
listen 8080 default_server;
server_name _;
root /var/www/ip_8080;
}
server {
listen 8080;
server_name api.example.com;
root /var/www/api;
}
在这个例子中,访问 http://192.168.1.1:8080 会命中第一个 server 块,而访问 http://api.example.com:8080 则会命中第二个。这种配置方式确保了无论用户是通过 IP 还是域名,都能得到正确的内容响应。如果省略 default_server,Nginx 会选择配置文件中第一个出现的 server 块作为默认响应,这可能导致不可预期的行为。
当 server_name 包含通配符时优先级如何判定
当 server_name 中包含通配符(如 *.example.com)或正则表达式时,Nginx 按照精确匹配、最长通配符前缀、最长通配符后缀、正则表达式顺序进行优先级判定。IP 访问始终由 default_server 处理,不受这些规则影响,除非该 server 块未被标记为默认且没有更具体的匹配项。
server {
listen 80;
server_name *.example.com;
root /var/www/wildcard;
}
server {
listen 80;
server_name ~^sub\d+\.example\.com$;
root /var/www/regex;
}
在上述配置中,如果请求的 Host 头是 test.example.com,它将匹配通配符规则;如果是 sub1.example.com,它可能匹配正则表达式规则(取决于具体版本和配置细节,通常通配符优先于正则)。但无论如何,如果用户直接通过 IP 访问,只要有一个 server 块标记了 default_server,它就会优先响应。如果没有标记,则按配置文件中的顺序选择第一个 server 块。因此,在处理混合解析时,显式设置 default_server 是最可靠的做法。











