检查请求是否为https
,一般可以通过$_SEVER
变量中HTTPS
和端口是否是443
判断:
function isHttps(){
return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
|| $_SERVER['SERVER_PORT'] == 443;
}
前面工作中遇到微信分享失败(没有缩略图的样式),检查原因是签名失败。通过日志发现签名计算的url
地址是http
开头的,并非https
,但我访问的地址是https
。将$_SERVER
加入日志中查看,
发现$_SERVER
中没有HTTPS
变量,SERVER_PORT
也是80
端口,但看到了另外两个值为https
的变量:HTTP_X_FORWARDED_PROTO
和HTTP_X_CLIENT_PROTO
。在搜索引擎中检索HTTP_X_FORWARDED_PROTO
, 可以在MDN中看到X_FORWARDED_PROTO
的解释:
The X-Forwarded-Proto (XFP) header is a de-facto standard header for identifying the protocol (HTTP or HTTPS) that a client used to connect to your proxy or load balancer. Your server access logs contain the protocol used between the server and the load balancer, but not the protocol used between the client and the load balancer. To determine the protocol used between the client and the load balancer, the X-Forwarded-Proto request header can be used.
就是说当网站有使用代理或者负载均衡时,这时服务器判断是否是https
,需要通过HTTP_X_FORWARDED_PROTO
判断,因为代理或者负载均衡和服务器之间可能通过http
通信的。所以上面的方法应
改为:
function is_ssl(){
return isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 1 || strtolower($_SERVER['HTTPS']) === 'on')
|| isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443
|| isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'
|| isset($_SERVER['HTTP_X_CLIENT_PROTO']) && $_SERVER['HTTP_X_CLIENT_PROTO'] === 'https';
}