Node.js应用非根路径无法加载,Nginx代理配置问题求助
Node.js应用Nginx代理后/projectb路径资源加载失败问题
最近折腾Nginx代理Node.js应用的时候踩了个坑,跟大家唠唠:
我的Node.js应用跑在127.0.0.1:8081,一开始的Nginx配置是这样的,/和/projectb路径都能正常加载页面,啥毛病都没有:
server { listen 80; location / { proxy_pass http://127.0.0.1:8081; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } location /projectb { proxy_pass http://127.0.0.1:8081/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
结果后来我调整了配置,加了个/somethingelse的代理指向另一个服务,这下好了——/projectb路径没法完全加载页面了!浏览器网络面板里一堆资源(图片、JS文件,还有些接口请求)全失败了。修改后的配置大概是这样的:
server { listen 80; location /somethingelse { proxy_pass http://127.0.0.1:8080/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } # 原来的/projectb配置要么被修改要么遗漏了 }
问题到底出在哪?
其实核心就是Nginx代理的斜杠处理和请求匹配规则:
- proxy_pass的斜杠是关键:
- 之前
/projectb的配置里,proxy_pass末尾加了/,这相当于把/projectb这个前缀“剥离”掉,把剩下的路径直接拼到127.0.0.1:8081的根路径下。比如请求/projectb/img/logo.png,会被代理到http://127.0.0.1:8081/img/logo.png,刚好匹配Node.js应用里的资源路径。 - 如果后来你不小心把
/projectb的proxy_pass末尾的/去掉了,或者干脆没写这个location,那请求/projectb/img/logo.png就会被代理到http://127.0.0.1:8081/projectb/img/logo.png——而你的Node.js应用根本没有/projectb这个路径下的资源,自然就404了。
- 之前
- 请求匹配顺序:Nginx会优先匹配更具体的location,所以
/projectb要比/的配置更先被匹配到才行,如果你的新配置遗漏了/projectb的location,所有/projectb开头的请求都会走到/的location,这时候proxy_pass没加/,就会把完整路径带过去,导致资源找不到。
怎么解决?
其实很简单,把原来的/projectb配置补回来,确保它的proxy_pass末尾带着/,并且放在合适的位置就行。完整的正确配置应该是这样的:
server { listen 80; # 先匹配/projectb,确保优先处理 location /projectb { proxy_pass http://127.0.0.1:8081/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # 可选:加上这些头,让Node.js应用能拿到正确的请求信息 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # 新加的/somethingelse代理 location /somethingelse { proxy_pass http://127.0.0.1:8080/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } # 其他所有请求走默认的Node.js应用代理 location / { proxy_pass http://127.0.0.1:8081; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
另外,要是还不行,就打开浏览器的开发者工具,看看失败请求的URL是什么——比如如果请求的是/projectb/js/app.js,那肯定是proxy_pass的斜杠没加对;如果是/js/app.js404,那得检查Node.js应用是不是正确托管了静态资源。
内容的提问来源于stack exchange,提问作者atkayla
相关产品推荐
相关产品推荐

