【问题标题】:Redirect Loop while redirecting all http requests to https using .htaccess重定向循环,同时使用 .htaccess 将所有 http 请求重定向到 https
【发布时间】:2013-08-20 06:45:52
【问题描述】:

我的 .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]

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

【问题讨论】:

  • 哪个 URL 导致了重定向循环?
  • 它们在一个空白的 htaccess 文件中对我来说都可以正常工作。您确定您的 https 重定向没有丢失www
  • @JonLin 如果它对你有用,那么它应该对我有用。但它不起作用。是的,我的 https 重定向没有丢失 www。这是RewriteRule (.*) https://www.example.com/$1 [R=301,L]www。我猜服务器设置或其他方面可能存在一些问题。

标签: apache .htaccess


【解决方案1】:

以防万一有人在负载均衡器后面使用 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]

【讨论】:

  • 是的,你是对的!我有同样的问题。但是我不能让你的代码工作,我用这个代替:RewriteEngine On RewriteCond %{SERVER_PORT} 80 RewriteRule ^(.*)$ https://domain.com/$1 [R,L]
  • 感谢康斯坦丁,一直在寻找。 HTTP:X-Forwarded-Proto 解决了它。
  • 非常感谢!负载均衡器是我的罪魁祸首
【解决方案2】:

我看到很多人在尝试使用 .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[""] 位。

【讨论】:

  • @z-m,真正有用的答案让我找到了自己的解决方案。我只能推荐看看phpinfo() 输出。它可以为您节省数小时的麻烦。赞一个!
  • 或 ENV:HTTPS 而不仅仅是 HTTPS,就像我的重定向循环一样!
【解决方案3】:

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

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

正确的做法是actually explained in their support site:

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

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

【讨论】:

【解决方案4】:

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

像@z-m 建议的那样,我使用 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;
  }

【讨论】:

    【解决方案5】:
    RewriteEngine on
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{
    

    【讨论】:

    • 虽然此代码可能会回答问题,但提供有关 why 和/或 如何 回答问题的额外上下文将显着改善其长期价值。请edit你的答案添加一些解释。
    【解决方案6】:

    在我的情况下是:

    if ($_SERVER['HTTPS'] != "on")
    

    【讨论】:

      猜你喜欢
      • 2014-06-30
      • 1970-01-01
      • 2017-04-30
      • 1970-01-01
      • 2018-01-18
      • 2014-10-08
      • 1970-01-01
      • 1970-01-01
      • 2011-05-04
      相关资源
      最近更新 更多