17

我的 .htaccess 文件有以下规则

# to redirect http to https
RewriteCond %{HTTPS} off
RewriteRule (.*) https://www.example.com/$1 [R=301,L]

# to redirect urls with index.php to /
RewriteCond %{THE_REQUEST} ^.*/index.php 
RewriteRule ^(.*)index.php$ /$1 [R=301,L]

# to redirect non www requests to www url
RewriteCond %{HTTP_HOST} !^www\.example\.com 
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]

当我尝试访问该网站时,它变成了一个重定向循环。如何解决此问题并正确重定向?

4

6 回答 6

34

以防万一有人在负载均衡器后面使用 Apache http-> https 重写时有重定向循环,这里的解决方案对我有用。

当负载均衡器执行 SSL 工作时,在负载均衡器后面为 Apache使用RewriteCond %{HTTPS} off时,我遇到了同样的问题。

如果站点的 https 版本不是通过 Apache ModSSL 配置的,它不会将 %{HTTPS} 变量设置为“on”并保持无限重定向。

修复它的最简单的解决方案是将所有 https 流量定位到另一个 Apache VirtualHost(当 SSL 由负载平衡器处理时),它是主要的副本,但具有不同的端口(比如说 81)。在 .htaccess 中,对不在端口 81 上的所有内容执行 mod_rewrite:

ReWriteCond %{SERVER_PORT} !^81$
RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R,L]

第二种方法是将 X-Forwarded-Proto 标头从负载均衡器发送到 Apache 并在重写条件下使用它:

RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
于 2013-11-01T07:45:57.660 回答
14

我看到很多人在尝试使用 .htaccess 文件从 http 移动到 https 时遇到重定向循环。对于如何解决这个问题,有很多不同的答案。有人说:

ReWriteCond %{SERVER_PORT} 80
OR
RewriteCond %{HTTPS} off
OR
RewriteCond %{HTTPS} !on
OR (as above)
RewriteCond %{HTTP:X-Forwarded-Proto} !https
OR EVEN
RewriteCond %{HTTP:X-Forwarded-SSL} =off

但这些都不适合我。我最终发现了基本事实,即不同的服务器以不同的方式配置,并且它们都提供不同的服务器变量。

如果上述方法都不适合您,那么诀窍是使用 PHP 找出您的特定服务器在您访问 http 页面时发送给您的环境变量,以及当您访问 https 页面时它发送给您的环境变量,以及然后您可以使用该变量进行重定向。只需使用以下代码在您的服务器上创建一个 PHP 文件(例如 showphpvars.php):

<?php phpinfo() ?>

然后用浏览器查看。找到其中包含 _SERVER["HTTP_HOST" (etc)] 的变量部分,并寻找一个在 http 与 https 之间发生变化的变量。我的结果是一个名为 SSL 的变量,在使用 https 时设置为 1,而在使用 http 时根本没有设置。

我使用该变量通过 PHP 重定向到 https,这比使用 htaccess 好得多,但我认为任何 _SERVER 变量也可以使用 htaccess 访问,如果您希望继续使用它。只需在引号内使用名称,不要使用 PHP 添加的 _SERVER[""] 位。

于 2015-03-14T17:08:24.803 回答
7

供您参考,这实际上取决于您的托管服务提供商。正如康斯坦丁在另一个答案中所述,它可能正在使用负载均衡器。

在我的情况下(Infomaniak),上面没有任何实际工作,我得到了无限重定向循环。

他们的支持网站实际上解释了正确的方法:

RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://your-domain.com/$1 [R=301,L]

因此,请务必咨询您的托管服务提供商。希望他们有一篇文章解释如何做到这一点。否则,请寻求支持。

于 2017-11-30T09:32:11.690 回答
1

如果无论您在 htaccess 中执行什么操作都出现重定向循环,请改为在 PHP 中执行重定向。

就像@zm 建议的那样,我使用 phpinfo() 来查找在使用 SSL 时发生变化的变量。就我而言,它是 $_SERVER['HTTP_X_PROTO'] == "https"。不在 SSL 上时,不会设置此变量。

这是我用来从 HTTP 重定向到 HTTPS 的代码:

  if ($_SERVER['HTTP_X_PROTO'] != "https") {
    header("HTTP/1.1 301 Moved Permanently");
    $location = "https://" . $_SERVER[HTTP_HOST] . $_SERVER[REQUEST_URI];
    header("Location: $location");
    exit;
  }
于 2016-01-05T12:55:37.580 回答
0
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{
于 2016-06-20T16:31:28.340 回答
0

就我而言,它是:

if ($_SERVER['HTTPS'] != "on")
于 2017-06-30T02:28:56.233 回答