目录
[避坑指南:Nginx 多层代理下的"404"与"重定向死循环"深度排查](#避坑指南:Nginx 多层代理下的“404”与“重定向死循环”深度排查)
[一、 问题现象](#一、 问题现象)
[二、 核心原因分析](#二、 核心原因分析)
[1. 优先级陷阱:正则匹配"劫持"了转发](#1. 优先级陷阱:正则匹配“劫持”了转发)
[2. 路径消失之谜:斜杠的艺术](#2. 路径消失之谜:斜杠的艺术)
[3. 协议丢失导致的重定向死循环](#3. 协议丢失导致的重定向死循环)
[三、 解决方案:标准转发模板](#三、 解决方案:标准转发模板)
[1. 外部网关(宝塔/站点)配置](#1. 外部网关(宝塔/站点)配置)
[2. Docker 打包与缓存清理](#2. Docker 打包与缓存清理)
[四、 排查工具箱](#四、 排查工具箱)
[五、 总结](#五、 总结)
避坑指南:Nginx 多层代理下的"404"与"重定向死循环"深度排查
在复杂的微服务或企业级应用部署中,我们经常使用多层 Nginx 架构:外层 Nginx(如宝塔面板)负责 HTTPS 卸载和全局入口,内层 Nginx(如 Docker 容器)负责业务逻辑分发。
最近在部署 MaxKey 认证系统(基于 Angular 开发)时,遇到了一个极其隐蔽的坑:后端 curl 正常,但域名访问静态资源报 404,且页面陷入重定向死循环。 本文将复盘排查过程并提供标准配置方案。
一、 问题现象
-
静态资源 404 :浏览器访问
[https://domain.com/maxkey/assets/js.js](https://domain.com/maxkey/assets/js.js)报错 404,但直接在服务器curl内网 IP 资源却是通的。 -
重定向次数过多 :页面无法打开,提示
ERR_TOO_MANY_REDIRECTS。 -
Docker 缓存困惑:修改前端代码并重新打包镜像,发现页面内容始终不更新。
二、 核心原因分析
1. 优先级陷阱:正则匹配"劫持"了转发
这是宝塔等集成环境最常见的坑。宝塔默认会在站点配置中添加如下代码:
Nginx
location ~ .*\.(js|css)?$ {
expires 12h;
# ...
}
Nginx 匹配规则是: 正则匹配(~)的优先级高于普通前缀匹配(location /maxkey/)。
当请求 .js 文件时,Nginx 会进入宝塔默认的正则块,试图在本地目录下找文件。由于文件实际在 9 号机的容器里,本地自然返回 404,转发逻辑根本没触发。
2. 路径消失之谜:斜杠的艺术
在 proxy_pass 中,结尾是否有斜杠 / 决定了路径是"替换"还是"透传":
-
proxy_pass http://ip/path/;(带斜杠):会切掉 location 匹配的部分。 -
proxy_pass http://ip;(不带斜杠):会完整保留路径转发。 -
后果 :如果配置不当,后端收到的请求会变成
/assets/js(丢失了/maxkey/),导致 Angular 路由因找不到 Base-Href 而崩溃。
3. 协议丢失导致的重定向死循环
外层走 HTTPS (443),内层走 HTTP (80)。如果外层没有告诉内层"用户实际用的是 HTTPS",内层 Nginx 可能会尝试发送 301 重定向让用户跳转到 HTTP,而外层又强制 HTTPS,从而导致无限循环。
三、 解决方案:标准转发模板
为了彻底解决上述问题,建议在外部网关(如宝塔)中使用 ^~(最佳前缀匹配)。它能强制跳过正则匹配,确保转发逻辑生效。
1. 外部网关(宝塔/站点)配置
Nginx
# 使用 ^~ 确保优先级高于宝塔默认的 .js/.css 正则块
location ^~ /maxkey/ {
# 显式指向内网业务服务器 IP 与端口
proxy_pass http://10.130.135.9:8527/maxkey/;
# 关键头部透传
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 核心:告诉后端当前协议是 HTTPS,防止重定向循环
proxy_set_header X-Forwarded-Proto $scheme;
# 禁用可能导致冲突的自动重定向修改
proxy_redirect off;
}
2. Docker 打包与缓存清理
如果您发现代码不更新,通常是 Docker 认为 dist 目录没有变化。请在构建时禁用缓存:
Bash
# 强制重新拷贝 dist 目录
docker build --no-cache -t maxkey-frontend:latest .
# 启动时强制重新创建容器
docker-compose up -d --force-recreate maxkey-frontend
四、 排查工具箱
-
抓包对比 :同时在两台机器执行
tail -f观察日志,对比GET路径是否一致。 -
无痕模式 :301 重定向会被浏览器深度缓存,修改配置后必须 用
Ctrl+Shift+N测试。 -
配置校验 :修改
daemon.json或nginx.conf后,务必先用nginx -t或相关工具校验语法,再执行reload。
五、 总结
在处理多层代理时,优先级 、路径透明度 、协议识别 是三大核心。使用 ^~ 锁定路径优先级,配合 X-Forwarded-Proto 维持协议状态,可以解决 90% 以上的转发异常。
作者:Gao Song (高松)
场景:农业 AI 专利管理系统部署实践