Nginx反向代理多应用的配置问题及链接跳转异常求助
Nginx反向代理多应用的配置问题及链接跳转异常求助
嘿,我来帮你梳理下问题所在,以及对应的解决方案~
首先先明确你的场景和核心问题:
你有三个内网应用,想要通过Nginx的路径前缀(/app1/、/app2/、/app3/)反向代理访问,但现在遇到两个问题:
app1的根路径xxx.xxx.xxx.xx1/app1/无法访问,只有/app1/login能正常打开- 应用内部的链接跳转都丢失了前缀,直接跳到
xxx.xxx.xxx.xx1/new-page/而非xxx.xxx.xxx.xx1/app1/new-page
问题原因分析
- 根路径无法访问:当你访问
/app1/时,后端应用可能返回了302跳转(比如跳转到/login),但Nginx默认不会修改后端返回的Location响应头,导致浏览器直接跳转到没有前缀的/login,而这个路径在你的Nginx配置里没有对应的代理规则,所以报错。 - 链接跳转丢失前缀:你的应用是基于根路径(
/)开发的,生成的所有绝对路径链接(比如href="/login")都没有带上/app1前缀,浏览器会直接以Nginx的根路径去请求,自然找不到对应的资源。
修正后的完整Nginx配置
下面是调整后的配置,我会逐段解释关键点:
server { listen 80; server_name xxx.xxx.xxx.xx1; # 全局启用gunzip(如果后端返回压缩响应,Nginx需要解压后才能做内容替换) gunzip on; # 代理app1的配置 location /app1/ { # 1. 把/app1/前缀去掉,转发到后端的根路径 rewrite ^/app1/(.*)$ /$1 break; # 2. 基础代理头配置 proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; # 保持请求的Host头,让后端知道是通过Nginx访问的 proxy_set_header X-Forwarded-Proto $scheme; # 传递协议(http/https) # 3. 代理到后端app1地址(注意末尾不要加斜杠,配合rewrite使用) proxy_pass https://xxx.xxx.xxx.xx2:3000; # 4. 解决后端跳转的Location头问题:把后端返回的根路径跳转替换成带/app1前缀的路径 proxy_redirect https://xxx.xxx.xxx.xx2:3000/ /app1/; # 5. 替换应用内的绝对路径链接,确保跳转和资源请求都带上/app1前缀 sub_filter 'href="/' 'href="/app1/'; sub_filter 'src="/' 'src="/app1/'; sub_filter 'action="/' 'action="/app1/'; sub_filter_once off; # 替换所有匹配项,而不只是第一个 # 如果后端是自签名HTTPS证书,需要添加这个跳过证书验证(仅内网环境使用) proxy_ssl_verify off; } # 代理app2的配置(逻辑和app1完全一致,替换对应地址即可) location /app2/ { rewrite ^/app2/(.*)$ /$1 break; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass https://xxx.xxx.xxx.xx3:5000; proxy_redirect https://xxx.xxx.xxx.xx3:5000/ /app2/; sub_filter 'href="/' 'href="/app2/'; sub_filter 'src="/' 'src="/app2/'; sub_filter 'action="/' 'action="/app2/'; sub_filter_once off; proxy_ssl_verify off; } # 代理app3的配置(http协议,去掉ssl相关配置) location /app3/ { rewrite ^/app3/(.*)$ /$1 break; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://xxx.xxx.xxx.xx4; proxy_redirect http://xxx.xxx.xxx.xx4/ /app3/; sub_filter 'href="/' 'href="/app3/'; sub_filter 'src="/' 'src="/app3/'; sub_filter 'action="/' 'action="/app3/'; sub_filter_once off; } # 默认路径:访问根路径可以跳转到app1,或者返回404 location / { rewrite ^/(.*)$ /app1/$1 last; # 或者直接返回404:return 404; } }
关键配置点说明
- rewrite规则:
rewrite ^/app1/(.*)$ /$1 break;会把/app1/xxx这样的请求,去掉前缀后转发到后端的/xxx,确保后端能识别正确的路径。 - proxy_redirect:这个指令专门用来修改后端返回的
Location响应头,把后端的根路径跳转(比如/login)替换成带前缀的/app1/login,解决根路径访问跳转异常的问题。 - sub_filter:这个模块会替换应用响应内容里的绝对路径链接,把所有
href="/"、src="/"这类不带前缀的链接,替换成带/app1/前缀的形式,确保应用内的跳转和资源加载都能正确指向Nginx的代理路径。 - proxy_ssl_verify off:如果你的后端HTTPS用的是自签名证书,Nginx默认会验证证书有效性,内网环境下可以关闭验证避免报错。
额外注意事项
- 确保你的Nginx安装了
ngx_http_sub_filter_module模块(大部分官方包都默认包含,如果没有的话需要重新编译Nginx添加该模块)。 - 如果应用返回的是压缩后的响应(比如gzip),一定要开启
gunzip on,否则sub_filter无法正常替换内容。 - 后续绑定域名后,只需要把
server_name改成你的域名即可,其他配置无需改动。
备注:内容来源于stack exchange,提问作者daydr3am3r
相关产品推荐
相关产品推荐

