Nginx能否通过单域名/子域名实现多端口多站点访问
核心结论
完全可以实现,这种同端口下靠域名/子域名区分不同站点的配置,是Nginx最基础的虚拟主机能力,不需要额外装插件,调整配置即可实现。
实现逻辑
你之前觉得困惑的点,本质是没搞懂Nginx的请求匹配顺序:
- 当用户发起HTTP请求时,首先会根据输入的域名+端口,把请求发到对应IP的对应端口上;
- Nginx收到请求后,第一步先确认请求的目标端口,筛出所有
listen配置和请求端口一致的server块; - 第二步对比请求头里的
Host字段(也就是用户输入的域名),和筛出来的server块里的server_name做匹配,匹配优先级是“完全匹配>通配符匹配>正则匹配”,匹配到哪个就走哪个站点的规则。
也就是说,只要所有站点的监听端口统一,靠server_name绑定不同的域名/子域名,用户访问时根本不需要手动输入端口号。
针对你现有配置的改造方案
你现在的配置是两个站点分别监听80、1900端口,且server_name都写的localhost,所以必须靠端口区分。最符合你需求的改法是两个站点统一监听80端口,靠不同的server_name绑定子域名,改造后不需要让用户记端口。
步骤1:配置域名解析(本地开发不需要买域名)
因为你是本地开发环境,不需要走公网DNS解析,直接修改系统hosts文件,把两个域名都指向本地回环地址即可:
- Windows系统hosts文件路径:
C:\Windows\System32\drivers\etc\hosts - 在文件末尾追加两行:
127.0.0.1 domain.com 127.0.0.1 test.domain.com
保存后,系统会把这两个域名的解析直接指向本机,不需要走公网。
步骤2:修改Nginx配置
把原来的两个server块做调整,全部监听80端口,分别绑定对应的域名,原有站点的缓存、路由规则全部保留不动:
# 测试站点配置 server { listen 80; server_name test.domain.com; # 绑定测试子域名 location / { root D:\testwebsite; index index.html index.htm; expires -1; add_header Pragma "no-cache"; add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"; try_files $uri$args $uri$args/ $uri $uri/ /index.html =404; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } # 生产站点配置 server { listen 80; server_name domain.com; # 绑定主域名 location / { root D:\prodwebsite; index index.html index.htm; expires -1; add_header Pragma "no-cache"; add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"; try_files $uri$args $uri$args/ $uri $uri/ /index.html =404; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
步骤3:验证生效
- 先在Nginx的可执行文件目录下,运行
nginx -t检查配置语法有没有错误; - 没有问题的话执行
nginx -s reload重载配置; - 浏览器直接访问
domain.com就会打开生产站点,访问test.domain.com就会打开测试站点,不需要加任何端口号。
可选方案说明
如果你不想把两个站点都统一到80端口,一定要保留现有1900端口跑测试站点的结构,也能绑定域名,但体验会打折扣:
- 只需要把测试站点的
server_name改成test.domain.com,保留原来的listen 1900配置即可; - 但因为1900不是HTTP协议的默认端口,用户访问时必须手动输入
test.domain.com:1900才能匹配到对应站点,和之前直接输IP加端口的体验没有本质区别,一般不推荐这么配。
常见踩坑点
- 如果浏览器开了加密DNS(DoH/DoT)功能,本地hosts配置可能不生效,需要把对应的测试域名加到浏览器的例外列表里;
- Nginx匹配server块是先按端口过滤、再按域名匹配,要是域名没匹配到任何server块,会自动走同端口下的默认server,很容易出现站点串用的问题,配置完一定要逐个验证域名的访问结果;
- 原来的1900端口如果没有其他服务在用,完全可以把对应的listen配置删掉,减少不必要的端口暴露。
内容的提问来源于stack exchange,提问作者Rasyue
相关产品推荐
相关产品推荐

