
摘要: 你是否也曾在 Docker 中运行 WordPress,并通过反向代理(如 NPM、Nginx)为其配置了精美的 HTTPS 域名,却不幸遭遇了无休止的 ERR_TOO_MANY_REDIRECTS 错误?别担心,你不是一个人!本文将深入剖析这个常见问题的根源,并为你揭示一个简单而强大的 wp-config.php 配置技巧,让你彻底摆脱重定向的噩梦。
(一) 噩梦的开始:当 HTTPS 遇上反向代理
想象一下这个场景:你在群晖(或其他宿主机)上通过 Docker 轻松部署了 WordPress,并且为了安全和专业,你使用了 Nginx Proxy Manager (NPM) 或其他反向代理工具,将你的域名(比如 https://a.b.com:8443)指向了这个 WordPress 实例。你满心欢喜地配置好了 SSL 证书,一切看起来都那么完美。
然而,当你尝试访问你的网站时,浏览器却无情地抛出了 ERR_TOO_MANY_REDIRECTS。页面在 http 和 https:// 之间疯狂跳转,仿佛陷入了一个无法逃脱的怪圈。
我的踩坑实录(可简述你的初始配置):
网络架构: 群晖 Docker -> WordPress (容器端口 80 映射到宿主机 9092) + NPM (处理所有入站流量,包括 SSL)。
域名与端口: https://a.b.com:8443 (因特殊原因未使用标准 443 端口)。
NPM 配置: 将 a.b.com:8443 的 HTTPS 流量转发到 WordPress 的 HTTP 地址 http://[群晖IP]:9092。
WordPress 初始配置: wp-config.php 和数据库中的 siteurl、home 均设置为最终的 HTTPS 地址 https://a.b.com:8443/。
结果?熟悉的重定向地狱。
(二) 为什么 WordPress 会“迷路”?重定向循环的根源
要理解这个问题,我们首先要知道 WordPress 是如何判断当前访问是 HTTP 还是 HTTPS 的。
当用户的请求链条是这样的:
浏览器 --(HTTPS)--> 反向代理 (NPM) --(HTTP)--> WordPress
反向代理的职责: NPM 接收到来自浏览器的 HTTPS 请求。它负责处理 SSL/TLS 加密解密。然后,它通常会以普通的 HTTP 方式将请求转发给后端的 WordPress 应用。这是常见的做法,称为“SSL 终止 (SSL Termination)”。
WordPress 的视角: WordPress 直接感知到的是来自 NPM 的 HTTP 请求。
冲突点: 如果此时 WordPress 的 siteurl 和 home 设置为 https://...,WordPress 会认为:“我的配置是 HTTPS,但现在这个请求是 HTTP 的,这不安全/不正确,我必须把它重定向回 HTTPS!”
循环发生: WordPress 发出重定向指令,浏览器再次请求 HTTPS 地址,反向代理再次解密并以 HTTP 转发...周而复始。
(三) 柳暗花明:wp-config.php 中的关键一行
define('FORCE_SSL_ADMIN', true); // 建议:强制后台使用 SSL
// ↓↓↓ 核心中的核心 ↓↓↓
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
$_SERVER['HTTP_HOST'] = $_SERVER["HTTP_X_FORWARDED_HOST"]; // 注意:NPM 或你的反向代理需要正确设置 X-Forwarded-Host
$_SERVER['SERVER_PORT'] = $_SERVER["HTTP_X_FORWARDED_PORT"]; // 注意:NPM 或你的反向代理需要正确设置 X-Forwarded-Port
}
这段代码在做什么?
define('FORCE_SSL_ADMIN', true);: 这是一个好习惯,它会强制 WordPress 后台(/wp-admin/)始终使用 HTTPS。
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'):
$_SERVER['HTTP_X_FORWARDED_PROTO']: 当反向代理转发请求时,它通常会添加一些特殊的 HTTP 头部信息来告诉后端应用原始请求的一些情况。X-Forwarded-Proto 就是这样一个头部,它表明原始客户端(浏览器)是使用什么协议(http 或 https://)连接到代理的。
这行代码检查是否存在这个头部,并且其值是否为 https。
$_SERVER['HTTPS'] = 'on';: 如果上述条件成立(即原始请求是 HTTPS),这行代码会“欺骗”或“告知”WordPress:“嘿,当前这个请求实际上是通过 HTTPS 来的!” WordPress 内部的 is_ssl() 函数等就会因此返回 true。
$_SERVER['HTTP_HOST'] = $_SERVER["HTTP_X_FORWARDED_HOST"];:
X-Forwarded-Host 头部包含了原始请求的域名。
这行代码将 PHP 用来判断当前请求主机名的 $_SERVER['HTTP_HOST'] 变量,设置为反向代理传递过来的原始主机名。这对于 WordPress 生成正确的链接至关重要,特别是当内部端口和外部访问域名/端口不一致时。
$_SERVER['SERVER_PORT'] = $_SERVER["HTTP_X_FORWARDED_PORT"];:
X-Forwarded-Port 头部包含了原始请求的端口号。
这行代码将 PHP 用来判断当前请求端口的 $_SERVER['SERVER_PORT'] 变量,设置为反向代理传递过来的原始端口号。这对于非标准端口(如我的 :8443)的 HTTPS 访问尤为重要。
重要前提:确保你的反向代理正确设置了 X-Forwarded-* 头部! NPM 通常默认会做这件事。如果你使用其他代理,请检查其配置。
推荐的最佳实践:
在 wp-config.php 中加入上述关键代码。
将数据库中的 siteurl 和 home 仍然设置为你最终希望用户访问的、包含正确协议和端口的完整 HTTPS 地址,例如 https://a.b.com:8443/。
清除缓存: 清除浏览器缓存、CDN 缓存(如果使用)、以及 WordPress 可能有的缓存插
测试! 你的网站现在应该可以通过 HTTPS 正常访问,不再有重定向循环了。
WordPress 在反向代理环境下的 HTTPS 配置确实是一个常见的痛点,ERR_TOO_MANY_REDIRECTS 更是让人头疼。但正如我们所见,通过在 wp-config.php 中添加几行简单的代码,利用反向代理传递的 X-Forwarded-* 头部信息,我们就能让 WordPress 正确识别外部请求的真实情况,从而优雅地解决这个问题。
希望这篇文章能帮助到同样被此问题困扰的你,让你能更专注于内容创作,而不是配置的泥潭!如果你有其他技巧或经验,欢迎在评论区分享。