跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

如何解决 Nginx 配置了 proxy_set_header X-Forwarded-Proto https 依然死循环

应动态传递真实协议:proxy_set_header X-Forwarded-Proto $scheme;,避免硬编码https导致混合环境重定向死循环,并配合后端信任解析该头。 直接写死
proxy_set_header X-Forwarded-Proto https
是常见但危险的做法——它会让所有请求(包括真实 HTTP 请求)都“假装”是 HTTPS,后端无法区分真假,反而更容易触发重定向死循环。真正要解决的不是“加头”,而是“传对头”。 确认 X-Forwarded-Proto 的值是否动态准确 硬编码为
https
会掩盖协议差异,尤其在混合环境(如本地调试用 HTTP、生产走 HTTPS)、多级代理或 CDN 接入时必然出错。正确做法是让 Nginx 自动反射用户真实访问协议: 用
$scheme
动态传递:
proxy_set_header X-Forwarded-Proto $scheme;
避免写成
proxy_set_header X-Forwarded-Proto https;
或
http;
若有多级 Nginx(比如 CDN → 边缘 Nginx → 应用 Nginx),下级应读取上级传来的
$http_x_forwarded_proto
,而不是覆盖它 检查 Host 头是否被错误透传 Host 头错一个字符,就可能导致后端生成带端口(如
:8080
)或错误域名的跳转地址,浏览器再发请求回来,Nginx 又转发,形成套娃循环。 稿定在线PS PS软件网页版 下载 必须用
proxy_set_header Host $host;
(注意是
$host
,不是
$http_host
)
$http_host
会原样保留用户请求里的 Host(含端口),例如
example.com:443
,后端可能据此生成
https://example.com:443/login
,而该地址不可达
$host
自动剥离端口,只保留规范域名,更安全可靠 排查外部干扰源:CDN 或中间代理 Cloudflare、阿里云全站加速等 CDN 常是隐藏推手。例如: Cloudflare SSL 模式设为「灵活」→ CDN 用 HTTP 回源到你的 Nginx → 你的 Nginx 却又强制跳 HTTPS → 循环 解决方案:CDN 端改用「完全」或「完全(严格)」模式,并关闭「自动 HTTPS 重写」功能 同时检查宝塔等面板是否残留
return 301 https://
规则,即使开关已关,配置文件里也可能还藏着 验证后端是否真正信任转发头 光传头不够,后端必须主动读取并信任这些头。以 WordPress 为例: 仅靠
X-Forwarded-Proto
不足以让
is_ssl()
返回 true,需在
wp-config.php
中补上逻辑: if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {$_SERVER['HTTPS'] = 'on';} 其他框架(如 Spring Boot)需启用
ForwardedHeaderFilter
并设置
server.forward-headers-strategy=framework

相关文章