直接看 nginx access.log 中的 $upstream_http_location 字段可定位重定向协议错误,若其值为 http://127.0.0.1:8080/login 或 localhost,则表明后端未识别真实 https 协议;需结合 $status、$upstream_status 和 error.log 中 connect()/timeout/reset 错误综合排查,并确认 proxy_set_header x-forwarded-proto $scheme 与 host $host 已正确配置且后端启用对应头解析。

直接看 Nginx access.log 里的 $upstream_http_location 字段,它能暴露后端返回的原始跳转地址。如果这个值是 http://127.0.0.1:8080/login 或 http://localhost/,就说明后端根本没识别出用户实际走的是 HTTPS,协议信息在代理链中丢失了。
盯住三个关键日志字段
打开 /var/log/nginx/access.log,每行请求记录里重点比对:
- $status:Nginx 最终返回给浏览器的状态码。如果是 302 但浏览器卡在 HTTP 跳转,说明重定向已发出但内容不对。
-
$upstream_status:后端真实返回的状态码。若看到
302 302,代表后端确实发出了重定向;若为302 502,说明后端响应还没发完连接就断了。 -
$upstream_http_location:这是最核心的线索。它原样记录后端响应头中的 Location 值。只要里面出现内网 IP、
http://开头、或带错误端口(如:8080),就能确认协议和主机上下文没传到位。
快速筛查异常跳转
不用手动翻日志,用命令直接抓问题现场:
- 查内网地址泄露:
awk '$9==302 {print $13}' /var/log/nginx/access.log | grep -E "(192\.|10\.|127\.|localhost|:[0-9]{4})" | tail -5 - 对比登录前后跳转差异:
grep "/login" /var/log/nginx/access.log | tail -3和grep "/dashboard" /var/log/nginx/access.log | tail -3并排看$upstream_http_location是否一致。
配合 error.log 定位底层原因
access.log 告诉你“跳错了”,error.log 才告诉你“为什么错”:
- 出现
connect() failed (111: Connection refused)→ 后端服务未运行,302 是 Nginx 自己生成的错误页,不是真实重定向。 - 出现
upstream timed out→ 后端处理太慢,Nginx 在等 Location 头时超时,可能返回 504。 - 出现
recv() failed (104: Connection reset by peer)→ 后端拒绝了带 X-Forwarded-* 头的请求,常见于未配置可信代理 IP 或协议头校验失败。
验证 Nginx 是否透传了协议标识
检查配置中是否漏掉这行,且位置正确:
-
proxy_set_header X-Forwarded-Proto $scheme;必须写在location块里,且在proxy_pass之前或之后均可(主流框架都支持两种位置)。 - 不能写死成
https,否则 HTTP 入口或测试环境会失效。 - 同时确认
proxy_set_header Host $host;已设置,避免后端因 Host 错误而降级协议或触发循环代理。
确认后端是否真正信任并解析该头
仅 Nginx 发送不够,后端必须主动启用解析逻辑:
- Spring Boot:加配置
server.forward-headers-strategy=framework,并确保 Nginx IP 在可信代理列表中。 - .NET Core:调用
UseForwardedHeaders()中间件,并设Options.ForwardedProtoHeaderName = "X-Forwarded-Proto"。 - Java Tomcat:启用
RemoteIpFilter,指定protocolHeader="x-forwarded-proto"。











