使用 PHP 从 HTTP 重定向到 HTTPS
Posted
技术标签:
【中文标题】使用 PHP 从 HTTP 重定向到 HTTPS【英文标题】:Redirecting from HTTP to HTTPS with PHP 【发布时间】:2011-07-03 15:23:24 【问题描述】:我正在开发一个购物车网站,我想在用户输入帐单详细信息时将用户重定向到 HTTPS 页面,并在他注销之前保持下一页的 HTTPS 连接。
为了做到这一点,我需要在服务器上安装什么(我正在使用 Apache),以及如何从 php 完成重定向?
【问题讨论】:
【参考方案1】:你可以随时使用
header('Location: https://www.domain.com/cart_save/');
重定向到保存 URL。
但我建议通过 .htaccess 和 Apache 重写规则来完成。
【讨论】:
我总是建议在重定向之前检查 $_SERVER['HTTPS']。 $_SERVER['HTTPS'] 并不总是设置,但最好先检查一下。这就是为什么我建议在 Apache 中使用一个有用的重写规则来做到这一点,它只在它不在 HTTPS 上时重定向。 虽然 Apache 建议不要使用额外的 .htaccess 文件(因为它会变慢),而是使用 Apache 的 *.conf 中的重写规则。【参考方案2】:尝试这样的事情(应该适用于 Apache 和 IIS):
if (empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === "off")
$location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $location);
exit;
【讨论】:
它并不总是有效。我尝试使用它,但 $_SERVER 数组中没有“https”元素,因此它给出了“重定向过多”的错误。需要使用其他方法。 我必须测试if( $_SERVER['HTTPS'] == "off")
才能使此代码正常工作。我认为这是因为我在 IIS 上,而不是像 OP 这样的 Apache。
注意:die() 或 exit() 放在标头重定向之后可能很重要,以防止页面的其余部分执行(并可能向客户端发送额外信息)(即黑客或浏览器)可能不尊重标题)。
根据您的服务器环境/设置,您可能需要使用 $_SERVER['HTTP_X_FORWARDED_PROTO'] 来检查 http/https
这是否容易受到注入攻击?如果$_SERVER['REQUEST_URI']
包含特殊字符,比如换行符怎么办?【参考方案3】:
在 IIS 上使用 PHP 从 HTTP 重定向到 HTTPS
我无法重定向到 HTTPS 以在 Windows 服务器上工作 它运行 MS Internet Information Services (IIS) 版本 6。我更 以前在 Linux 主机上使用 Apache,所以我转向 Internet 帮助,这是我搜索时排名最高的 Stack Overflow 问题 对于 “php 将 http 重定向到 https”。但是,选择的答案不起作用 对我来说。
经过反复试验,我发现使用 IIS,$_SERVER['HTTPS']
是
对于非 TLS 连接,设置为 off
。我认为下面的代码应该
帮助通过搜索引擎提出此问题的任何其他 IIS 用户。
<?php
if (! isset($_SERVER['HTTPS']) or $_SERVER['HTTPS'] == 'off' )
$redirect_url = "https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header("Location: $redirect_url");
exit();
?>
编辑:来自另一个Stack Overflow answer,
一个更简单的解决方案是检查if($_SERVER["HTTPS"] != "on")
。
【讨论】:
@JakeSylvestre 够公平的。鉴于此问题未标记为apache
,我发布此答案是为了其他 IIS 用户(类似于我所处的情况),他们可能会通过搜索引擎访问此页面。我同意这样的观点,即答案是为了整个社区的利益,而不仅仅是 OP。【参考方案4】:
这是一个很好的方法:
<?php
if (!(isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' ||
$_SERVER['HTTPS'] == 1) ||
isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
$_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'))
$redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $redirect);
exit();
?>
【讨论】:
运行良好,标记为良好的会返回重定向太多次,至少在 Chrome 中 条件!(isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on'
将始终为假,因为如果最后一部分为真,则第一部分为假。
@Max:我不明白你说什么。如果第二个条件为真($_SERVER['HTTPS'] == 'on'),那么第一个条件也必须为真(当然设置了服务器变量,因为它包含一个值!)
它对我有用,谢谢!【参考方案5】:
在我的 AWS beanstalk 服务器上,我没有看到 $_SERVER['HTTPS'] 变量。我确实看到 $_SERVER['HTTP_X_FORWARDED_PROTO'] 可以是“http”或“https”,因此如果您在 AWS 上托管,请使用:
if ($_SERVER['HTTP_HOST'] != 'localhost' and $_SERVER['HTTP_X_FORWARDED_PROTO'] != "https")
$location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $location);
exit;
【讨论】:
以上是关于使用 PHP 从 HTTP 重定向到 HTTPS的主要内容,如果未能解决你的问题,请参考以下文章
php - 标头位置重定向:https 到 https,http 到 http
PHP:将主域重定向到https:// www,子域重定向到https://(不带www)