Nginx 的 server_name 默认不区分大小写,统一转为小写匹配;如需区分,必须使用带 ~ 开头的正则表达式,并注意转义、引号及匹配优先级。

Nginx 的 server_name 默认不区分大小写,这是由其内部的哈希查找机制决定的——无论你在配置中写 WWW.EXAMPLE.COM、www.example.com 还是 Www.ExAmPlE.CoM,Nginx 都会统一按小写处理并完成匹配。
但如果你需要显式控制大小写行为(比如强制区分),唯一可行的方式是改用正则表达式匹配,因为只有正则支持区分大小写的语法。
✅ 正确做法:用 ~ 开头的区分大小写正则
server {
listen 80;
server_name ~^WWW\.example\.com$; # 仅匹配全大写的 WWW
root /var/www/www-upper;
}
server {
listen 80;
server_name ~^www\.example\.com$; # 仅匹配全小写的 www
root /var/www/www-lower;
}⚠️ 注意事项:
- 必须用引号包裹整个正则(虽然部分版本可省略,但强烈建议加双引号,避免解析错误):
server_name "~^WWW\.example\.com$";
- 点号
.在正则中需转义为\.,否则表示“任意字符” -
^和$保证完全匹配,防止WWW1.example.com之类误匹配 - 正则匹配只在精确匹配和通配符都未命中时触发,所以要确保没有更优先的
server_name www.example.com;存在,否则正则不会被用到
❌ 常见误解澄清
server_name WWW.example.com;和server_name www.example.com;
→ 在同一server块中写多个等价域名,或不同server块中写大小写变体,都不会生效区分效果,Nginx 会把它们视为相同域名处理。没有
case_sensitive on/off这类开关指令
→ Nginx 不提供全局或局部开启/关闭server_name大小写敏感的配置项。使用
if ($host = "WWW.example.com") { ... }不解决根本问题
→if是运行时判断,不能替代server_name的路由分发逻辑,且if在server块中限制多、易出错,不推荐用于 host 路由。
? 实际调试建议
-
启动前检查配置语法:
nginx -t
-
查看 Nginx 加载的
server_name列表(含正则):nginx -T 2>/dev/null | grep "server_name"
-
抓包或查看 access 日志,确认客户端实际发送的
Host头:192.168.1.100 - - [25/Sep/2026:20:54:12 +0000] "GET / HTTP/1.1" 200 123 "-" "curl/8.1.2" "WWW.example.com"
这样就能验证请求是否真的带了你期望的大小写 Host 值。
不复杂但容易忽略


















