Nginx非根路径proxy_pass反向代理失败问题求助
Nginx反向代理子路径失效问题排查与修复
问题场景
Windows 10系统下配置Nginx反向代理,将/myapp/路径代理至后端服务http://172.17.122.45:8100/,但访问http://server:8009/myapp/时,页面能加载JS文件,但部分JSON、图片资源无法加载。浏览器控制台显示资源请求路径为根路径(如http://server:8009/assets/envsettings.json),而非预期的/myapp/子路径下的资源。
当前Nginx配置
#user nobody; worker_processes 1; error_log "C:\\nginx\\nginx-1.23.1\\logs\\error.log"; events { worker_connections 1024; } http { default_type application/octet-stream; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; gzip on; include "C:\\nginx\\nginx-1.23.1\\conf\\mime.types"; server { listen 8009; server_name server; default_type application/octet-stream; location / { root html; index index.html index.htm; } location /myapp/ { proxy_pass http://172.17.122.45:8100/; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $server_name; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr; #sub_filter_types *; sub_filter 'action="/' 'action="/myapp/'; sub_filter 'href="/' 'href="/myapp/'; sub_filter 'src="/' 'src="/myapp/'; sub_filter_once off; } } }
浏览器控制台报错
main.5e06c118abe3f1a0.js:1 ERROR Error: Uncaught (in promise): zx: {"headers":{"normalizedNames":{},"lazyUpdate":null},"status":200,"statusText":"OK","url":"http://server:8009/assets/envsettings.json","ok":false,"name":"HttpErrorResponse","message":"Http failure during parsing for http://server:8009/assets/envsettings.json","error":{"error":{},"text":"<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"/><base href=\"/\"/><meta content=\"width=device-width,initial-scale=1\" name=\"viewport\"/><meta content=\"#081C42\" media=\"(prefers-color-scheme: light)\" name=\"theme-color\"/><meta content=\"#081C42\" media=\"(prefers-color-scheme: dark)\" name=\"theme-color\"/><meta content=\"MinIO Console\" name=\"description\"/><link href=\"./styles/root-styles.css\" rel=\"stylesheet\"/><link href=\"./apple-icon-180x180.png\" rel=\"apple-touch-icon\" sizes=\"180x180\"/><link href=\"./favicon-32x32.png\" rel=\"icon\" sizes=\"32x32\" type=\"image/png\"/><link href=\"./favicon-96x96.png\" rel=\"icon\" sizes=\"96x96\" type=\"image/png\"/><link href=\"./favicon-16x16.png\" rel=\"icon\" sizes=\"16x16\" type=\"image/png\"/><link href=\"./manifest.json\" rel=\"manifest\"/><link color=\"#3a4e54\" href=\"./safari-pinned-tab.svg\" rel=\"mask-icon\"/><title>MinIO Console</title><script defer=\"defer\" src=\"./static/js/main.44b939e3.js\"></script><link href=\"./static/css/main.90d417ae.css\" rel=\"stylesheet\"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id=\"root\"><div id=\"preload\"><img src=\"./images/background.svg\"/> <img src=\"./images/background-wave-orig2.svg\"/></div><div id=\"loader-block\"><img src=\"./Loader.svg\"/></div></div></body></html>"}}
问题原因
- 页面基准路径错误:后端返回的HTML中包含
<base href="/">标签,该标签会强制所有相对路径的请求都基于根路径/解析,而非当前的/myapp/子路径,这是核心问题。 - 路径替换不完整:当前
sub_filter仅替换了action、href、src属性中的根路径,但遗漏了<base>标签,以及JS脚本中发起的资源请求(如fetch('/assets/envsettings.json')这类绝对路径调用)。 - 内容过滤范围受限:默认
sub_filter仅处理text/html类型的响应,JS、JSON等类型的内容未被过滤,导致脚本中的路径无法被替换。
修复方案
修改后的Nginx配置
#user nobody; worker_processes 1; error_log "C:\\nginx\\nginx-1.23.1\\logs\\error.log"; events { worker_connections 1024; } http { default_type application/octet-stream; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; gzip on; include "C:\\nginx\\nginx-1.23.1\\conf\\mime.types"; server { listen 8009; server_name server; default_type application/octet-stream; location / { root html; index index.html index.htm; } location /myapp/ { proxy_pass http://172.17.122.45:8100/; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $server_name; proxy_set_header X-Real-IP $remote_addr; # 启用所有类型内容的替换 sub_filter_types *; # 替换base标签,修正页面基准路径 sub_filter '<base href="/">' '<base href="/myapp/">'; # 替换HTML中的绝对路径引用 sub_filter 'action="/' 'action="/myapp/'; sub_filter 'href="/' 'href="/myapp/'; sub_filter 'src="/' 'src="/myapp/'; # 替换JS中可能出现的绝对路径请求(如fetch、axios调用) sub_filter '"/assets/' '"/myapp/assets/'; sub_filter '"/static/' '"/myapp/static/'; # 全局替换所有根路径开头的引用(可选,需根据实际情况调整,避免误替换) # sub_filter '"/' '"/myapp/'; sub_filter_once off; } # 兜底配置:如果仍有资源请求走根路径的assets/static,直接代理到后端 location ~ ^/(assets|static)/ { proxy_pass http://172.17.122.45:8100/$1/; proxy_set_header Host $host; } } }
关键修改点说明
- 启用
sub_filter_types *;:让Nginx对所有类型的响应内容执行路径替换,包括JS、JSON等。 - 替换
<base href="/">:将页面基准路径改为/myapp/,从根源上修正所有相对路径的解析基准。 - 补充路径替换规则:新增针对JS中常见资源路径(如
/assets/、/static/)的替换,覆盖脚本发起的请求。 - 添加兜底代理规则:防止仍有遗漏的资源请求走根路径,直接将
/assets/和/static/路径代理到后端服务。
内容的提问来源于stack exchange,提问作者Akhila
相关产品推荐
相关产品推荐

