You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Nginx会选用server_name为_的server块处理http://example.pro请求?

Nginx HTTP请求匹配异常问题解析

问题描述

访问https://example.pro时一切正常,但访问http://example.pro时,Nginx却返回了server_name _那个server块的内容。确认请求的Host头和server_name example.pro完全匹配,而且HTTPS协议下这个server块明明能正常工作。

提供的Nginx配置

http {
    sendfile on;
    tcp_nopush on;
    types_hash_max_size 2048;
    server_tokens on;
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;
    access_log /_nginx_logs/access.log;
    error_log /_nginx_logs/error.log;
    gzip on;

    server {
        server_name www.example.pro;

        listen 80;
        listen 443 ssl;

        return 301 https://example.pro$request_uri;
        ssl_certificate "/etc/letsencrypt/live/www.example.pro/fullchain.pem";
        ssl_certificate_key "/etc/letsencrypt/live/www.example.pro/privkey.pem";        
    }

    server {
        server_name example.pro

        listen 80;
        listen 443 ssl;

        ssl_certificate "/etc/letsencrypt/live/example.pro/fullchain.pem";
        ssl_certificate_key "/etc/letsencrypt/live/example.pro/privkey.pem";        

        location / {
            proxy_pass http://localhost:3000;
        }

        location /api {
            proxy_pass http://localhost:7500;
            proxy_set_header X-Forwarded-For $remote_addr;
        }
    }

    server {
        server_name _;
        listen 80 default_server;

        location / {
            root /projects/site-stub;
        }
    }
}

问题原因

问题出在第二个server块里的server_name example.pro——这行末尾少了个分号;。

Nginx的配置语法有硬性要求:所有指令必须以分号结尾。少了分号会导致配置解析混乱:

  • 这行server_name指令无法被正确识别,Nginx根本不知道这个server块是用来处理example.pro的请求的
  • 当80端口的HTTP请求进来时,Nginx找不到匹配Host: example.pro的server块,就会自动用配置里标记为default_server的那个(也就是server_name _的块)
  • 至于HTTPS能正常工作,是因为加载配置时,这个server块里的HTTPS相关指令(比如listen 443 ssl、证书配置)没被这个语法错误完全搞崩,还能被Nginx解析到,所以HTTPS请求能匹配上

解决方法

给server_name example.pro末尾加上分号,修正后的代码片段如下:

server {
    server_name example.pro;

    listen 80;
    listen 443 ssl;

    ssl_certificate "/etc/letsencrypt/live/example.pro/fullchain.pem";
    ssl_certificate_key "/etc/letsencrypt/live/example.pro/privkey.pem";        

    location / {
        proxy_pass http://localhost:3000;
    }

    location /api {
        proxy_pass http://localhost:7500;
        proxy_set_header X-Forwarded-For $remote_addr;
    }
}

改完之后执行命令重新加载Nginx配置就行:

nginx -s reload

内容的提问来源于stack exchange,提问作者Dmitriy Zhuravlev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 20:05:23