我在网上看到过很多教程,说你需要检查$_SERVER['HTTPS'],如果服务器连接是HTTPS安全的。我的问题是,在我使用的一些服务器上,$_SERVER['HTTPS']是一个未定义的变量,导致错误。是否有另一个变量我可以检查,总是应该定义?

只是为了清楚一点,我目前正在使用这段代码来解决它是否是一个HTTPS连接:

if(isset($_SERVER['HTTPS'])) {
    if ($_SERVER['HTTPS'] == "on") {
        $secure_connection = true;
    }
}

当前回答

$secure_connection = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || (!empty($_SERVER['HTTP_HTTPS']) && $_SERVER['HTTP_HTTPS'] != 'off') || $_SERVER['REQUEST_SCHEME'] == 'https' || $_SERVER['SERVER_PORT'] == 443) ? true : false;

代码正在检查任何可能的东西,也可以在IIS web服务器上工作。Chrome自v44不设置头HTTP: 1,所以检查HTTP_HTTPS是OK的。如果这段代码不匹配https,这意味着您的web服务器或代理服务器配置不佳。Apache本身设置HTTPS标志正确,但当你使用代理(例如nginx)时可能会有问题。你必须在nginx https虚拟主机中设置一些头文件

proxy_set_header   X-HTTPS 1;

并使用一些Apache模块通过从代理中查找X-HTTPS来正确设置HTTPS标志。搜索mod_fakessl, mod_rpaf等。

其他回答

只是出于兴趣,铬金丝雀目前发送

HTTPS : 1

发送到服务器,这取决于服务器的配置方式,可能意味着您将返回以下内容

HTTPS : 1, on

这破坏了我们的应用程序,因为我们正在测试是否打开,而它显然没有打开。 目前,只有铬金丝雀似乎可以做到这一点,但值得注意的是,金丝雀的东西通常会在“正常”铬短时间后落地。

我的系统使用cloudflare。我必须访问$_SERVER['HTTP_CF_VISITOR']值。

$isSsl = false; 
    if (isset($_SERVER['HTTP_CF_VISITOR'])) {
        $cfDecode = json_decode($_SERVER['HTTP_CF_VISITOR']);
        if (!empty($cfDecode) && !empty($cfDecode->scheme) && $cfDecode->scheme == 'https') {
            $isSsl = true;
        }
    }
var_dump($isSsl);

您可以检查$_SERVER['SERVER_PORT'],因为SSL通常运行在端口443上,但这并不是万无一失的。

我使用了这里的主要建议,当没有设置HTTPS时,日志中的“PHP通知”让我很恼火。你可以使用空合并操作符"?? ?":

if( ($_SERVER['HTTPS'] ?? 'off') == 'off' ) {
    // redirect
}

(注意:在php v7之前不可用)

这就是我解决这个问题的方法

$https = !empty($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'on') === 0 ||
        !empty($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
            strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') === 0;

return ($https) ? 'https://' : 'http://';