使用Nginx反向代理,可以不显示端口号吗:3 种写法一次讲清

编程狮(w3cschool.cn) 2026-11-01 07:05:44 浏览数 (20)
反馈

用 Nginx 做反向代理,浏览器地址栏不显示后端端口号是默认就能做到的:用户访问走 80/443,Nginx 在内部把请求转发给 proxy_pass 指向的带端口后端,端口发生在内网,浏览器无从得知。所以“不显示端口号”本身就是反向代理的天然行为,真正的坑只有两个——proxy_pass 怎么写、以及后端跳转时别把端口漏出去。下面把单站点、多站点、端口漏出去三种情况一次讲清,并给出可验证的最小配置,照着配基本能一次跑通。

Nginx 反向代理让浏览器不显示后端端口号的三种写法

先看结论

  • 不显示端口是默认行为:用户走 80/443,Nginx 内部转发到带端口后端,端口号对用户不可见。
  • 单站点最常用:一个 server 块监听 80/443,proxy_pass 指向 http://127.0.0.1:端口。
  • 多站点共用端口:用不同 server_name 区分,各自反代不同后端端口。
  • 端口漏出去的元凶是 Location 头:后端返回 Location: http://x:端口/ 时要用 proxy_redirect 改写。
  • 改完 nginx -t 校验再 reload,最后 curl -I 看 Location 确认端口号没露出来。

一、先弄清“不显示端口”到底指什么

前置条件:你已有一个跑在带端口后端(如 8080、3000)的服务,并且装好了 Nginx 可做反代。本文示例以 HTTP 为主,HTTPS 只需把 listen 改成 443 并配证书,隐藏端口号的逻辑完全一致。

很多人搜这个问题,其实是两种诉求混在一起:一种是“我不想让用户看到后端跑在 8080”,这本来就能做到;另一种是“我想让 Nginx 自己也换个端口”,那是改 listen,和反向代理无关。本文只讲第一种:用户访问域名,Nginx 把请求转给后端端口号,地址栏始终干净。

原理一句话:Nginx 在“服务端”完成转发,浏览器只跟 Nginx 的 80/443 通信,后端的端口号发生在内网。只要你访问的是 http://域名 而不是 http://域名:8080,端口就不会出现在地址栏。**适用边界**:前端资源(JS/CSS)里如果把后端地址硬编码成带端口的绝对 URL,浏览器仍会直接命中那个端口,这不属于反代能解决的范畴。先把 Nginx 入门指南 的 proxy_pass 认熟,回来更好懂。

实操时,先安装并配置好 Nginx 与后端服务,运行 nginx -t 命令做语法检查,确认预期能正常通过;若失败,按报错的行号定位并修复 proxy_pass 或 server 块里的写法,再验证一遍。单站点场景最省心:一个 server 监听 80/443,proxy_pass 指向 http://127.0.0.1:端口,浏览器永远只看到域名,后端端口被挡在内网。多站点场景同样走 80/443,靠 server_name 区分不同域名,各自反代到不同后端端口,彼此互不影响。真正容易露馅的是后端做了 302 跳转:它返回的 Location 头里带着 127.0.0.1:端口,浏览器一旦跟随就会被带上端口。解决办法不是改 proxy_pass,而是在 location 里加 proxy_redirect,把后端回的带端口地址改写成干净地址。改完务必用 curl -I 看响应头确认 Location 不再含端口,否则地址栏还是会暴露后端。

二、三种写法一次看清

2.1 写法一:单站点标准反代(最常见)

一个 server 块监听 80,把请求转给本机 8080:

server {
    listen 80;
    server_name example.com;
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

访问 http://example.com,地址栏干净,后端 8080 完全隐蔽。这是 90% 场景的答案,不需要任何额外技巧。配置要点:proxy_set_header Host $host 让后端拿到正确域名,否则某些应用会生成带错域名的跳转。

2.2 写法二:多站点共用 80/443,各反代不同端口

一台机器跑多个后端(8080 和 3000),用 server_name 区分,全部走同一个 80 端口:

server {
    listen 80;
    server_name a.example.com;
    location / { proxy_pass http://127.0.0.1:8080; }
}
server {
    listen 80;
    server_name b.example.com;
    location / { proxy_pass http://127.0.0.1:3000; }
}

用户访问 a/b 子域名都走 80,Nginx 按域名把流量分给不同后端端口号,端口依旧不可见。边界:适合同机多站点;若后端要独立域名证书,再各自加 443 server 块即可。

2.3 写法三(反例):端口是怎么漏出去的

端口“漏”出来的典型场景是后端做了 302 跳转,返回 Location: http://127.0.0.1:8080/login,浏览器就被带上了端口。这不是反代失败,是 Location 头没改写:

location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_redirect http://127.0.0.1:8080/ /;
}

proxy_redirect 把后端回的带端口 Location 改写成不带端口的地址,跳转后地址栏仍然干净。失败处理:若改完还露端口,先确认 proxy_redirect 的源地址和后端实际返回的 Location 前缀是否一致。更复杂的反代链路见 Nginxsysc 配置教程。

Nginx 反代隐藏端口号三种写法决策树

三、最小可用配置与验证

完整跑通的最小配置(含跳转改写):

server {
    listen 80;
    server_name example.com;
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_redirect http://127.0.0.1:8080/ /;
    }
}

验证与失败处理:nginx -t 通过再 reload。然后用 curl -sI http://example.com/login 看响应头里的 Location 是否还带 8080;如果带,说明 proxy_redirect 没匹配上,按后端真实 Location 前缀调整。性能提示:反代会多一跳网络,给后端加 keepalive 能明显降低延迟。HTTPS 站点把 listen 改成 443 配证书即可,隐藏端口与是否 HTTPS 无关。

Nginx 反代隐藏端口前后必查项速记卡

总结

Nginx 反向代理“不显示端口号”本来就是默认行为:用户走 80/443,Nginx 在内部转发到带端口后端。单站点用写法一(一个 server 监听 80/443 + proxy_pass),多站点用写法二(不同 server_name 共用端口各反代不同后端),端口漏出去几乎都是后端跳转的 Location 头没改写,用 proxy_redirect 补上即可。所谓“想显示端口”是反例,直接 listen 对应端口即可,别和反代隐藏端口搞混。上线前用 curl -I 打一遍各个深层路由,确认响应头里的 Location 都不带后端端口,这条检查比只看面板绿灯更可靠,能提前抓出 proxy_redirect 没匹配上的漏网之鱼。

常见问题

Q:为什么我配了反代,地址栏还是出现了 8080?

大概率是后端做了 302 跳转,返回带端口的 Location。在 location 里加 proxy_redirect http://127.0.0.1:8080/ /; 把端口抹掉即可,根因不在 proxy_pass。

Q:HTTPS 站点还能隐藏端口吗?

能。把 listen 改成 443 并配证书,proxy_pass 指向的后端端口依旧对内,用户只看到 https://域名。

Q:一个 Nginx 能反代多个不同端口的后端吗?

可以,用多个 server 块配不同 server_name,全部监听 80/443,各自 proxy_pass 到不同后端端口,互不影响。

Q:proxy_pass 末尾加不加斜杠有区别吗?

有。不带斜杠时 Nginx 把匹配到的 location 路径原样拼到后端;带斜杠时会把 location 前缀替换掉。路径错位是反代常见的隐性 bug,改完务必实测几个深层路由。

延伸学习

0 人点赞