WordPress因Nginx反向代理导致HTTPS跳转循环,需在wp-config.php中启用X-Forwarded-*头识别真实协议与主机,并在Nginx中透传X-Forwarded-Proto、X-Forwarded-Host等头,配合proxy_redirect重写Location响应头。

核心问题在于:WordPress 看到的是 Nginx 转发来的 HTTP 请求,却以为自己该跑在 HTTPS 下,于是拼命跳转;而 Nginx 又把跳转指令原样传回去,浏览器就卡在 http ⇄ https 之间反复横跳。解决的关键是让 WordPress “认清现实”——它实际运行在反向代理之后,真实协议和主机名得靠请求头来告诉它。
确保 WordPress 正确识别 HTTPS 和域名
WordPress 默认不信任 X-Forwarded-* 头,必须主动启用支持:
- 在 wp-config.php 文件开头(
之后)添加:
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}
- 同时确认数据库中
wp_options表的siteurl和home值为最终对外地址,例如https://example.com(不是http://localhost:8080或带端口的地址); - 若使用 Docker 部署,避免在环境变量中硬编码
WORDPRESS_SITE_URL,优先以数据库或 wp-config.php 为准。
Nginx 必须透传关键请求头
只转发 Host 不够,WordPress 需要明确知道原始请求是 HTTPS、来自哪个域名、哪个端口:
- 在对应
location /块中加入以下头信息:
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
-
X-Forwarded-Proto是最关键的——它让 WordPress 知道用户最初用的是 HTTPS; - 不要漏掉
X-Forwarded-Host,尤其当 Nginx 后端有多个域名共用同一 WordPress 实例时; - 若反向代理监听非标准端口(如 :8443),确保
$server_port能正确传递,或在 PHP 中忽略端口判断(见上一步 wp-config.php 逻辑)。
用 proxy_redirect 控制 Location 响应头改写
即使 WordPress 生成了含内部地址的跳转(比如 Location: http://172.18.0.3/login),Nginx 也能在发给浏览器前把它“掰正”:
- 在
location块中添加:
proxy_redirect ~^https://[^/]+(/.*)$ $scheme://$host$1;
- 这条正则规则会把后端返回的任意绝对 URL 的协议+域名部分,统一替换为当前请求的
$scheme://$host(即用户看到的地址); - 如果后端只返回相对路径(如
/wp-admin),此步可省略,但加上更稳妥; - 禁用自动重写(
proxy_redirect off)仅适用于你完全信任后端已正确生成跳转地址的场景,不推荐新手使用。
检查 proxy_pass 路径与 WordPress 上下文是否一致
路径截断错误会导致跳转目标被 Nginx 误判或 404,间接引发循环:
- 若 Nginx 配置为
location /blog/ { proxy_pass http://backend/; },则/blog/wp-login.php会被转发为/wp-login.php; - 此时 WordPress 若返回
Location: /blog/wp-admin,而 Nginx 没有匹配/blog/的 location 规则,请求就会失败或错配; - 建议:要么让 WordPress 运行在根路径(
location / { proxy_pass http://backend/; }),要么在 WordPress 中设置WP_HOME和WP_SITEURL为带子目录的完整 URL,并确保所有 Nginx location 块的路径前缀与之严格对应。











