必须在Nginx和Tomcat两端同时配置X-Forwarded-Proto透传与RemoteIpValve解析,缺一则重定向仍为HTTP;Nginx需加proxy_set_header X-Forwarded-Proto $scheme,Tomcat需配全RemoteIpValve的protocolHeader、remoteIpHeader和internalProxies。

必须在 Nginx 和 Tomcat 两端同时配置,缺一不可;只改 Nginx 或只改 Tomcat 都会失败。
为什么 Java 应用重定向会变成 HTTP
Tomcat 默认不信任反向代理传来的协议信息,response.sendRedirect() 生成的 Location 头直接使用 request.getScheme(),而这个值在 Nginx 转发后仍是 http(因为 Tomcat 实际收到的是 HTTP 请求)。即使浏览器访问的是 HTTPS,只要 Tomcat 没被告知“原始请求是 HTTPS”,它就会用 HTTP 构造重定向地址。
常见现象:https://example.com/login 提交后跳转到 http://example.com/dashboard,触发混合内容警告或被浏览器拦截。
- 关键判断依据:抓包看响应头
Location: http://... - 不是 Nginx 配置错误,而是 Tomcat 未启用“协议透传”逻辑
- Spring Boot 的
server.forward-headers-strategy=framework也不足以绕过此问题,底层仍依赖 Servlet 容器解析
proxy_set_header X-Forwarded-Proto $scheme 必须存在
这是让 Tomcat 知道原始协议的唯一可信来源。Nginx 必须显式把当前连接的协议($scheme)注入请求头,否则 Tomcat 收不到任何线索。
立即学习“Java免费学习笔记(深入)”;
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
正确写法(放在 location 或 server 块内):
proxy_set_header X-Forwarded-Proto $scheme;
- 不能写成
X-Forwarded-Proto https—— 硬编码会破坏 HTTP → HTTPS 自动跳转逻辑 - 不能漏掉分号,否则 Nginx 启动报错:
nginx: [emerg] invalid number of arguments in "proxy_set_header" directive - 该指令必须在
proxy_pass之前,否则不生效 - 不要同时设
X-Forwarded-Proto和X-Forwarded-Ssl on,后者已废弃且行为不一致
Tomcat 的 RemoteIpValve 配置不能只写一半
仅靠 Nginx 传头没用,Tomcat 必须主动读取并覆盖原始请求属性。核心是 RemoteIpValve,但必须配全三项:
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="X-Forwarded-For"
protocolHeader="X-Forwarded-Proto"
internalProxies="127\.0\.0\.1|10\.0\.0\.0/8|192\.168\.0\.0/16|172\.16\.0\.0/12" />
-
protocolHeader必须设为X-Forwarded-Proto,和 Nginx 传的头名严格一致(大小写敏感) -
internalProxies必须包含 Nginx 所在 IP 或网段,否则 Tomcat 会忽略该头(安全策略,默认只信 localhost) - 如果 Nginx 和 Tomcat 不在同一台机器,
internalProxies里要加 Nginx 的真实出口 IP,例如192\.168\.1\.10 - 别用
RemoteAddrValve或手动写 Filter 替代 —— 它们无法修改request.getScheme()的返回值
额外检查点:避免 proxy_redirect 干扰
Nginx 默认会重写后端返回的 Location 头,若 Tomcat 已正确生成 HTTPS 地址,proxy_redirect 反而可能把它又改回 HTTP。
- 确认是否启用了
proxy_redirect:搜索配置中是否有proxy_redirect http:// https://或proxy_redirect default - 推荐显式关闭:
proxy_redirect off;,让重定向逻辑完全交给 Tomcat 控制 - 如果必须用
proxy_redirect,确保规则匹配 HTTPS 场景,例如:proxy_redirect ~^http://(.*)$ https://$1; - 注意:Spring Boot 的
server.tomcat.remoteip.remote-ip-header配置只是简化 Valve 注册,底层仍依赖RemoteIpValve实际工作
最容易被忽略的是 internalProxies 的正则表达式——少一个反斜杠(如写成 192.168.0.0/16)会导致整个 Valve 失效,且无日志提示。

















