如何让反向代理子路径下的index.html指向正确资源路径?
问题背景
部署在/other-frontend/路径下的Docker前端应用,页面内资源使用绝对根路径(如/js/test.css),导致浏览器请求example.com/js/test.css,而实际资源存在于对应容器的根路径下,最终因返回404页面触发MIME类型错误:
Refused to apply style from 'https://example.com/js/test.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
Refused to execute script from 'https://example.com/js/test.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
方案1:Nginx响应内容重写(无需修改前端代码)
通过Nginx的sub_filter模块修改HTML响应内容,将资源的根路径引用替换为带/other-frontend/前缀的路径,同时新增location规则代理这些带前缀的资源请求到对应容器。
修改后的完整Nginx配置片段
upstream docker-frontend-1 { server 0.0.0.0:8000; } upstream docker-frontend-2 { server 0.0.0.0:9000; } server { listen 443 ssl default_server; listen [::]:443 ssl default_server; server_name example.com; location / { // 保持原有配置不变 } location /other-frontend/ { proxy_pass http://docker-frontend-2/other-frontend/; proxy_redirect http://docker-frontend-2 http://$lanIP$/other-frontend/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_cache_bypass $http_upgrade; proxy_connect_timeout 150; proxy_send_timeout 100; proxy_read_timeout 100s; # 重写HTML中的资源路径,替换根路径前缀 sub_filter '/js/' '/other-frontend/js/'; sub_filter '/css/' '/other-frontend/css/'; sub_filter_once off; # 替换所有匹配的资源引用 sub_filter_types text/html; # 仅处理HTML类型响应 } # 代理带前缀的资源请求到对应容器的根路径资源 location /other-frontend/js/ { proxy_pass http://docker-frontend-2/js/; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; } location /other-frontend/css/ { proxy_pass http://docker-frontend-2/css/; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; } }
方案2:修改前端<base>标签(允许修改前端代码时优先选择)
在前端index.html的<head>中添加<base>标签,指定页面所有资源的基准路径,同时调整资源引用为相对路径。
前端代码修改
<head> <!-- 指定基准路径,所有相对资源都会以此为前缀 --> <base href="/other-frontend/"> <!-- 资源路径改为相对路径,去掉开头的斜杠 --> <link rel="stylesheet" type="text/css" href="js/test.css" /> <script type="application/javascript" src="js/test.js"></script> </head>
对应Nginx配置调整
简化/other-frontend/的代理规则,直接将前缀路径映射到容器的根路径:
location /other-frontend/ { proxy_pass http://docker-frontend-2/; proxy_redirect http://docker-frontend-2 http://$lanIP$/other-frontend/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_cache_bypass $http_upgrade; proxy_connect_timeout 150; proxy_send_timeout 100; proxy_read_timeout 100s; }
内容的提问来源于stack exchange,提问作者King Reload

