WordPress 在负载均衡 / 内网穿透场景下 HTTPS 判断失效的原因与解决方案

VFX大学 wordpress开发 WordPress 在负载均衡 / 内网穿透场景下 HTTPS 判断失效的原因与解决方案

正在查看 1 条回复
  • 作者
    帖子
    • #948

      追光
      管理员

      在一些部署结构中,例如:

      • 使用 负载均衡(Load Balancer) 做反向代理

      • 使用 Nginx 做 SSL 终端,后端 WordPress 仍然走 HTTP

      • 使用 frp、ngrok 等内网穿透工具 作为 HTTPS 前端代理

      可能会遇到这样的问题:

      • WordPress 后台偶尔跳转到 http:// 开头的链接

      • 访问后台发布文章、上传图片等接口提示 “http 调用被阻止”

      • 前后台加载异常,提示“你的连接不是私密连接”

      究其原因,是 WordPress 无法正确判断当前请求是否为 HTTPS 所导致。


      一、根本原因解析

      WordPress 判断当前是否为 HTTPS,主要依赖:

      $_SERVER['HTTPS'] == 'on'

      然而在如下部署结构中:

      [客户端浏览器] —HTTPS→ [负载均衡 / 反代] —HTTP→ [WordPress 服务器]

      在真实的客户端和负载均衡之间是 HTTPS 没错

      但在负载均衡和后端 WordPress 之间是 HTTP

      于是后端收到的是:

      $_SERVER['HTTPS'] ≠ 'on'; // 判断失败

      这会导致 WordPress 做出一系列错误判断,例如:


      二、解决方法

      ✅ 方法 1:手动强制告诉 WordPress 当前访问是 HTTPS

      wp-config.phprequire_once ABSPATH . ‘wp-settings.php’; 上面加入以下代码:

      ////////////////////////// 负载均衡、反向代理 https 修正
      $_SERVER['HTTPS'] = 'on';
      define('FORCE_SSL_LOGIN', true);
      define('FORCE_SSL_ADMIN', true);

      推荐使用

      简单粗暴、生效立即。

      适用于:Nginx/Apache 反代、内网穿透、宝塔负载均衡、七层 SLB 等各种这类架构。

      ✅ 方法 2:使用标准反代头信息转发(更优雅)

      在反向代理(Nginx、Apache)中,把 HTTPS 信息转发到后端:

      Nginx 配置示例(推荐)

      location / {
          proxy_set_header X-Forwarded-Proto https;
          proxy_set_header X-Forwarded-Port 443;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_pass http://backend-ip:port;
      }

      然后在 wp-config.php 中判断该头信息:

      if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
          $_SERVER['HTTPS'] = 'on';
      }

      ⚠️ 专业生产环境下建议使用该方式,逻辑更清晰。


      三、可选增强配置

      为了彻底避免 WordPress 乱跳 http,可以加入以下常用配置:

      // 强制后台、登录页面走 https
      define('FORCE_SSL_LOGIN', true);
      define('FORCE_SSL_ADMIN', true);
      
      // 设置站点域名为固定的 HTTPS
      define('WP_HOME', 'https://yourdomain.com');
      define('WP_SITEURL', 'https://yourdomain.com');

      提示: WP_HOME 与 WP_SITEURL 推荐和数据库 wp_options 中的 Site URL 保持一致,否则会造成重定向循环。


      四、总结

      场景

      是否建议加 $_SERVER[‘HTTPS’]=on

      是否要传 X-Forwarded-Proto

      Nginx 自己做 SSL

      不需要

      HTTPS → 负载均衡 → HTTP → 主机

      建议

      建议

      frp/ngrok 内网穿透

      建议

      建议

      HTTP 全链路

      不需要

      ✅ 最简方案:直接在 wp-config.php 写入

      $_SERVER['HTTPS']='on';
      define('FORCE_SSL_LOGIN',true);
      define('FORCE_SSL_ADMIN',true);

    • #951

      追光
      管理员

      下面是整理「更完美方案」的标准做法,包括前端反代配置 + 后端 wp-config.php 配置的完整写法,便于直接复制使用👇

      ✅ 前端反向代理配置(Nginx 示例)

      确保在将请求转发给 WordPress 后端时,把真实的访问协议一起告诉它:

      location / {
          proxy_set_header X-Forwarded-Proto $scheme;    # 把 https/http 告诉后端
          proxy_set_header X-Forwarded-Port $server_port;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_pass http://backend-ip:port;
      }

      如果你的反代前端一定为 HTTPS,也可以写成:

      proxy_set_header X-Forwarded-Proto https;
      proxy_set_header X-Forwarded-Port 443;

      ✅ 后端 WordPress (wp-config.php) 识别写法

      在 wp-config.php 中找到:

      /** Sets up WordPress vars and included files. */
      require_once ABSPATH . ‘wp-settings.php’;

      在它上方加入下面这一段逻辑:

      /*
       * 如果是通过反代转发的 https,则强制告知 WordPress 当前是 https
       */
      if (
          isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
          strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https'
      ) {
          $_SERVER['HTTPS'] = 'on';
      }
      
      // 后台、登录强制 https(可选)
      define('FORCE_SSL_LOGIN', true);
      define('FORCE_SSL_ADMIN', true);

      🔄 流程示意图

      用户浏览器 (HTTPS)

      负载均衡 / Nginx 反代
      自动注入 X-Forwarded-Proto=https

      后端 WordPress 收到(HTTP),识别该头 → 设置 $_SERVER[‘HTTPS’]=’on’

      WordPress 正确判断 https,后台/资源全部走 https,无跳转问题 ✅

正在查看 1 条回复
  • 在下方一键注册,登录后就可以回复啦。