没写 server_name 是 Nginx 流量错乱最隐蔽也最常见的原因,它不报错却将未匹配域名的请求全部导入无名块,导致跨站访问或返回默认页;需用 nginx -T 检查生效配置、curl -H 模拟 Host 头验证路由,并为每个监听 80/443 的 server 块显式声明 server_name,含主域与通配子域,同时设 default_server 兜底拦截非法请求。
没写 server_name 是 Nginx 流量错乱最隐蔽也最常见的原因之一。它不会报错,也不会拒绝请求,而是悄悄把所有不匹配其他 server 块的流量,全部塞进这个“无名块”里——结果就是:你访问的是 api.example.com,却进了 blog.example.com 的配置,甚至返回了默认欢迎页或 404。
直接查生效配置,别只看自己改的文件:
nginx -T | grep "server {.*listen.*80|443" -A 10,逐个看每个监听 80/443 的 server 块里有没有 server_name 行listen 80; 或 listen 443 ssl; 却没跟 server_name 的块——它们就是潜在的“黑洞”server_name _; 或完全没这行,那它大概率就是兜底块用 curl 模拟真实请求,绕过 DNS 和浏览器缓存:
curl -v -H "Host: api.example.com" http://127.0.0.1 —— 看响应头、返回内容是否符合预期curl -v -H "Host: www.example.com" http://127.0.0.1,对比差异server_name,或者多个块都监听同一端口且没明确优先级Nginx 不会因为“你新建的配置在 conf.d 下”就自动优先使用它:
nginx -T | grep "listen.*default_server" -A 5,确认哪个块真正承担了 default_server 角色default_server,Nginx 会把第一个加载的同端口 server 块当作隐式兜底——而加载顺序取决于 include sites-enabled/* 展开时的字母序(如 00-default.conf 早于 10-api.conf)00-your-site.conf,reload 后再测试,若问题消失,就坐实是加载顺序抢跑了别依赖“不写就是默认”,要主动控制路由逻辑:
server 块只要监听 80/443,就必须带 server_name,哪怕只写一个域名server_name example.com www.example.com;
server_name example.com *.example.com;(*.example.com 不匹配 example.com)server { listen 80 default_server; server_name _; return 444; }