Nginx代理Express应用时,非Public应用无法加载CSS等静态资源
首次使用Nginx,目前运行三个Express应用:
- Public应用:
http://localhost:8080 - Admin应用:
http://localhost:1000 - Infra应用:
http://localhost:3000
需求是让每个应用通过Nginx反向代理时,都能正常加载各自的CSS、JS等静态资源。各应用已配置静态资源服务,例如Public和Admin应用中添加了如下代码:
this.express.use('/css',express.static(path.resolve(__dirname, 'css')));
直接访问各应用的端口时,静态资源均可正常加载;但通过Nginx反向代理访问时,仅Public应用正常,Admin和Infra应用的静态资源无法加载。当前Nginx配置文件如下:
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name localhost; proxy_redirect off; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; proxy_http_version 1.1; # PUBLIC location / { proxy_pass http://localhost:8080; } # ADMIN location /admin { proxy_pass http://localhost:1000; } # INFRA location /api { proxy_pass http://localhost:3000/api; } location /images { proxy_pass http://localhost:3000/images; } location /fonts { proxy_pass http://localhost:3000/fonts; } # ErrorPage error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
Admin应用路径不匹配:
当访问http://localhost/admin/css/style.css时,当前配置会把请求代理到http://localhost:1000/admin/css/style.css,但Admin应用的静态资源挂载在/css路径下,后端找不到/admin/css这个路径,导致静态资源404。Infra应用覆盖不全:
单独配置/images、/fonts的代理,但如果Infra应用还有其他静态资源路径(比如/js、/css)未配置,或者页面中使用相对路径引用资源,都会出现加载失败的情况。
1. 修正Admin应用代理配置
修改Admin的location规则,保证路径正确映射到后端静态资源:
# ADMIN location /admin/ { proxy_pass http://localhost:1000/; }
- 给
location和proxy_pass都加上末尾的/,Nginx会将/admin/之后的路径直接拼接到后端地址后,比如/admin/css/style.css会被代理到http://localhost:1000/css/style.css,正好匹配Admin应用的静态资源挂载路径。
2. 优化Infra应用代理配置
方案一:统一前缀代理(推荐)
给Infra应用设置统一前缀(比如/infra),避免和其他应用路径冲突,一次性覆盖所有请求:
# INFRA location /infra/ { proxy_pass http://localhost:3000/; }
这样访问/infra/api/xxx会代理到http://localhost:3000/api/xxx,/infra/images/xxx会代理到http://localhost:3000/images/xxx,无需单独配置每个静态资源目录。
方案二:保留原有路径补全配置
如果要保留现有路径,需补全所有静态资源的代理规则:
location /api { proxy_pass http://localhost:3000/api; } location /images { proxy_pass http://localhost:3000/images; } location /fonts { proxy_pass http://localhost:3000/fonts; } location /css { proxy_pass http://localhost:3000/css; } location /js { proxy_pass http://localhost:3000/js; }
修改后的完整Nginx配置
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name localhost; proxy_redirect off; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; proxy_http_version 1.1; # PUBLIC location / { proxy_pass http://localhost:8080; } # ADMIN - 修正路径映射 location /admin/ { proxy_pass http://localhost:1000/; } # INFRA - 统一前缀代理(推荐) location /infra/ { proxy_pass http://localhost:3000/; } # 若需保留原有路径,替换上面的INFRA配置为以下内容: # location /api { # proxy_pass http://localhost:3000/api; # } # location /images { # proxy_pass http://localhost:3000/images; # } # location /fonts { # proxy_pass http://localhost:3000/fonts; # } # location /css { # proxy_pass http://localhost:3000/css; # } # location /js { # proxy_pass http://localhost:3000/js; # } # ErrorPage error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
额外注意事项
- 修改配置后执行
sudo nginx -s reload重新加载配置生效。 - 确认各Express应用的静态资源目录存在且配置路径正确。
内容的提问来源于stack exchange,提问作者Joseph Oliveira

