开启HTTPS后WordPress显示不正常

1、问题点:由于服务器放在内网,用NPS从公网中转。开启HTTPS后,公网服务器还是用80端口连接内网,导致WordPress误以为没有开启HTTPS,css/js文件路径还是HTTP导致加载失败,页面显示不正常。

2、问题排查:网络搜索发现是wp-includes/load.php这个文件中的is_ssl()返回值异常。公网中转时返回值一直是false。

wp-includes/load.php 中只判断了$_SERVER['HTTPS'] 和$_SERVER['SERVER_PORT'] 字段,公网中转时这两个字段值还是http/80。

function is_ssl() {
    if ( isset( $_SERVER['HTTPS'] ) ) {
        if ( 'on' === strtolower( $_SERVER['HTTPS'] ) ) {
            return true;
        }
        if ( '1' === (string) $_SERVER['HTTPS'] ) {
            return true;
        }
    } elseif ( isset( $_SERVER['SERVER_PORT'] ) &&  ( '443' === (string) $_SERVER['SERVER_PORT'] ) ) {
        return true;
    }
    return false;
}

打印出 $_SERVER 所有值,发现里面有两个HTTP_X_FORWARDED字段标记了https和443,可以用来判断。

print_r($_SERVER);
Array
(
    ......
    [HTTP_X_FORWARDED_PROTO] => https
    [HTTP_X_FORWARDED_PORT] => 443
    ......
    [SERVER_PORT] => 80
    ......
    [REQUEST_SCHEME] => http    # 打印出来没有 $_SERVER['HTTPS']
    ......
)

3、问题解决:所以直接修改is_ssl()函数,增加对 HTTP_X_FORWARDED_PORT 和 HTTP_X_FORWARDED_PROTO 的判断即可。修改后的代码:

function is_ssl() {
    if ( isset( $_SERVER['HTTPS'] ) ) {
        if ( 'on' === strtolower( $_SERVER['HTTPS'] ) ) {
            return true;
        }
        if ( '1' === (string) $_SERVER['HTTPS'] ) {
            return true;
        }
    } elseif ( isset( $_SERVER['SERVER_PORT'] ) && ( '443' === (string) $_SERVER['SERVER_PORT'] ) ) {
        return true;
    }

    /* 以下两个判断新增加  */ 
    elseif ( isset( $_SERVER['HTTP_X_FORWARDED_PORT'] ) && ( '443' === (string) $_SERVER['HTTP_X_FORWARDED_PORT'] ) ) {
        return true;
    } elseif ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && ( 'https' === strtolower( $_SERVER['HTTP_X_FORWARDED_PROTO']) )) {
        return true;
    }

    return false;
}

测试访问正常。

THE END

标签: 虚拟网络

本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。


相关文章