我在网上看过很多教程,说你需要检查$_SERVER['HTTPS']
服务器连接是否用HTTPS保护.我的问题是,在我使用的某些服务器上,$_SERVER['HTTPS']
是一个未定义的变量导致错误.是否有另一个我可以检查的变量应该始终定义?
为了清楚起见,我目前正在使用此代码来解决它是否是HTTPS连接:
if(isset($_SERVER['HTTPS'])) { if ($_SERVER['HTTPS'] == "on") { $secure_connection = true; } }
Gras Double.. 269
即使$_SERVER['HTTPS']
未定义,这应始终有效 :
function isSecure() { return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443; }
该代码与IIS兼容.
从PHP.net文档和用户评论:
1)如果通过HTTPS协议查询脚本,则设置为非空值.
2)请注意,在IIS中使用ISAPI时,如果请求不是通过HTTPS协议进行的,则该值将为"off".(对于运行PHP作为Fast-CGI应用程序的IIS7,已经报告了相同的行为).
此外,$_SERVER['HTTPS']
即使安全连接,Apache 1.x服务器(以及损坏的安装)也可能没有定义.虽然不能保证,但按照惯例,端口443上的连接可能使用安全套接字,因此需要额外的端口检查.
即使$_SERVER['HTTPS']
未定义,这应始终有效 :
function isSecure() { return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443; }
该代码与IIS兼容.
从PHP.net文档和用户评论:
1)如果通过HTTPS协议查询脚本,则设置为非空值.
2)请注意,在IIS中使用ISAPI时,如果请求不是通过HTTPS协议进行的,则该值将为"off".(对于运行PHP作为Fast-CGI应用程序的IIS7,已经报告了相同的行为).
此外,$_SERVER['HTTPS']
即使安全连接,Apache 1.x服务器(以及损坏的安装)也可能没有定义.虽然不能保证,但按照惯例,端口443上的连接可能使用安全套接字,因此需要额外的端口检查.
我的解决方案(因为标准条件[$ _SERVER ['HTTPS'] =='on']在负载均衡器后面的服务器上不起作用)是:
$isSecure = false; if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') { $isSecure = true; } elseif (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || !empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on') { $isSecure = true; } $REQUEST_PROTOCOL = $isSecure ? 'https' : 'http';
HTTP_X_FORWARDED_PROTO:用于标识HTTP请求的原始协议的事实上的标准,因为反向代理(负载平衡器)可以使用HTTP与Web服务器通信,即使对反向代理的请求是HTTPS http://en.wikipedia.组织/维基/ List_of_HTTP_header_fields#Common_non,standard_request_headers
Chacha,根据PHP文档:"如果通过HTTPS协议查询脚本,则设置为非空值." 因此,在确实存在HTTPS的许多情况下,您的if语句将返回false.您需要验证是否$_SERVER['HTTPS']
存在且非空.如果没有为给定服务器正确设置HTTPS,您可以尝试检查是否$_SERVER['SERVER_PORT'] == 443
.
但请注意,某些服务器也将设置$_SERVER['HTTPS']
为非空值,因此请务必检查此变量.
参考:和[已弃用]的文档$_SERVER
$HTTP_SERVER_VARS
这在$_SERVER['HTTPS']
未定义时也有效
if( (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || $_SERVER['SERVER_PORT'] == 443 ){ //enable secure connection }
我刚刚遇到一个问题,我使用Apache mod_ssl运行服务器,但是phpinfo()和var_dump($ _SERVER)显示PHP仍然认为我在端口80上.
对于任何有同样问题的人来说,这是我的解决方法....
SetEnv HTTPS on DocumentRoot /var/www/vhost/scratch/content ServerName scratch.example.com
值得注意的是SetEnv系列.有了这个并且在重新启动之后,您应该拥有您梦寐以求的HTTPS环境变量
如果你正在使用Apache,你可能总是依赖
$_SERVER["REQUEST_SCHEME"]
验证所请求的URL的方案.但是,正如其他答案中所提到的,在假设确实使用SSL之前验证其他参数是明智的.
通过阅读之前的所有文章来发挥自己的作用:
public static function isHttps() { if (array_key_exists("HTTPS", $_SERVER) && 'on' === $_SERVER["HTTPS"]) { return true; } if (array_key_exists("SERVER_PORT", $_SERVER) && 443 === (int)$_SERVER["SERVER_PORT"]) { return true; } if (array_key_exists("HTTP_X_FORWARDED_SSL", $_SERVER) && 'on' === $_SERVER["HTTP_X_FORWARDED_SSL"]) { return true; } if (array_key_exists("HTTP_X_FORWARDED_PROTO", $_SERVER) && 'https' === $_SERVER["HTTP_X_FORWARDED_PROTO"]) { return true; } return false; }
真实答案:准备好复制粘贴到[config]脚本中
/* configuration settings; X=edit may 10th '11 */
$pv_sslport=443; /* for it might be different, as also Gabriel Sosa stated */
$pv_serverport=80; /* X */
$pv_servername="mysite.com"; /* X */
/* X appended after correction by Michael Kopinsky */
if(!isset($_SERVER["SERVER_NAME"]) || !$_SERVER["SERVER_NAME"]) {
if(!isset($_ENV["SERVER_NAME"])) {
getenv("SERVER_NAME");
// Set to env server_name
$_SERVER["SERVER_NAME"]=$_ENV["SERVER_NAME"];
}
}
if(!$_SERVER["SERVER_NAME"]) (
/* X server name still empty? ... you might set $_SERVER["SERVER_NAME"]=$pv_servername; */
}
if(!isset($_SERVER["SERVER_PORT"]) || !$_SERVER["SERVER_PORT"]) {
if(!isset($_ENV["SERVER_PORT"])) {
getenv("SERVER_PORT");
$_SERVER["SERVER_PORT"]=$_ENV["SERVER_PORT"];
}
}
if(!$_SERVER["SERVER_PORT"]) (
/* X server port still empty? ... you might set $_SERVER["SERVER_PORT"]=$pv_serverport; */
}
$pv_URIprotocol = isset($_SERVER["HTTPS"]) ? (($_SERVER["HTTPS"]==="on" || $_SERVER["HTTPS"]===1 || $_SERVER["SERVER_PORT"]===$pv_sslport) ? "https://" : "http://") : (($_SERVER["SERVER_PORT"]===$pv_sslport) ? "https://" : "http://");
$pv_URIprotocol
现在是正确的,随时可以使用; 例子$site=$pv_URIprotocol.$_SERVER["SERVER_NAME"]
.当然,字符串也可以替换为TRUE和FALSE.PV代表PortalPress Variable,因为它是一个永远有效的直接复制粘贴.这件作品可以在制作脚本中使用.