同一域名部署两个Node.js应用时出现MIME类型错误
Nginx反向代理Node.js应用路由问题排查与修复
问题场景
我有两个运行在不同端口的Node.js应用,配置了Nginx的两个location块实现反向代理:
# /etc/nginx/sites-available/my_site.com server { root /var/www/my_site.com/html; index index.html index.htm index.nginx-debian.html; server_name my_site.com www.my_site.com; location / { proxy_pass http://localhost:5001; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } location /app2 { proxy_pass http://localhost:5000; proxy_http_version 1.1; proxy_redirect off; } listen [::]:443 ssl ipv6only=on; # managed by Certbot listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/my_site.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/my_site.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot }
5001端口的应用运行正常,但访问5000端口的/app2时页面空白,控制台报错:
Refused to execute script from 'https://my_site.com/path/to/static/js/main.61886448.chunk.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
同时健康检查端点https://my_site.com/app2/api/health也无法访问,已确认静态文件存在且Nginx的http块包含include /etc/nginx/mime.types;,静态资源请求返回200状态码。
问题原因
- proxy_pass路径匹配错误:当请求
https://my_site.com/app2时,Nginx会将请求转发到http://localhost:5000,而非http://localhost:5000/app2。后端应用找不到对应路径,返回404页面(HTML格式),导致静态资源请求拿到的是HTML文件,触发MIME类型错误。 - 静态资源路径不匹配:前端打包时未设置正确的
publicPath,导致静态资源请求路径为根路径(/static/js/...),被location /规则转发到5001端口的应用,或者返回错误页面。 - 健康检查端点路由错误:用户访问
https://my_site.com/app2/api/health时,Nginx转发到http://localhost:5000/api/health,但后端应用的健康检查端点实际是/app2/api/health,导致无法匹配。
修复方案
1. 修正Nginx的proxy_pass配置
根据后端应用的路由结构选择以下两种配置之一:
- 如果后端应用路由以
/app2开头:location /app2 { proxy_pass http://localhost:5000/app2; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } - 如果后端应用的根路径(
/)对应前端的/app2路径:
注意这里location /app2/ { proxy_pass http://localhost:5000/; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }location和proxy_pass都要加尾斜杠,确保Nginx将/app2/后面的路径追加到后端的/之后。
2. 配置前端应用的publicPath
如果是React、Vue等前端框架,打包时设置publicPath为/app2/:
- React(
package.json):"homepage": "/app2/" - Vue(
vue.config.js):
这样静态资源的请求路径会变为module.exports = { publicPath: '/app2/' }https://my_site.com/app2/static/js/...,匹配location /app2的规则,正确转发到5000端口的应用。
3. 验证修复
重启Nginx使配置生效:
sudo systemctl restart nginx
访问https://my_site.com/app2检查页面是否正常加载,同时测试https://my_site.com/app2/api/health是否能返回正常响应。
内容的提问来源于stack exchange,提问作者Mike K
相关产品推荐
相关产品推荐

