在匹配URI Slug上启用SSL时重定向循环

时间:2013-02-20 20:16:46

标签: apache .htaccess mod-rewrite

我正在尝试使用mod_rewrite完成2个任务:

  1. 如果网址(无论协议)没有“www”子域名,请在网址中添加“www”。

  2. 如果URI以/secure.php开头并且协议不是https,则将协议切换为https。

  3. 所以我试过了:

    # Redirect to www subdomain
    RewriteCond %{HTTP_HOST} !^www\.
    RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
    
    # Force SSL for secure.php URIs
    RewriteCond %{HTTPS} off
    RewriteCond %{REQUEST_URI} ^/secure.php
    RewriteRule ^(.*)$ https://www.mysite.com%{REQUEST_URI} [R=301,L]
    

    但是在访问/secure.php URI时我得到了一个重定向循环。我无法弄清问题是什么,这就是我看到事件序列的方式:

    1. http://mysite.com/secure.php被请求
    2. 主机名包含“www”,因此它会传递第一个条件
    3. 网址已更新为http://www.mysite.com/secure.php,流程会循环回到顶部。
    4. 主机名 包含“www”,因此第一个条件失败并跳过重写。
    5. HTTPS 关闭,因此它与下一个条件AND
    6. 匹配
    7. URI以“/secure.php”开头,因此符合 所需条件
    8. 网址已更新为https://www.mysite.com/secure.php,流程会循环回到顶部。
    9. 主机名 包含“www”,因此第一个条件失败,并跳过重写。
    10. HTTPS 关闭,因此它无法完成下一个条件并跳过重写。
    11. 我做对了吗?我在这里做错了什么?

      我还在.htaccess中有另外一条规则,用于从ExpressionEngine网址中删除index.php:

      RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule ^(.*)$ /index.php/$1 [L]
      

      所以这是整个.htaccess文件:

      RewriteEngine On
      RewriteBase /
      
      # Remove index.php from ExpressionEngine URIs
      RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule ^(.*)$ /index.php/$1 [L]
      
      # Redirect to www subdomain
      RewriteCond %{HTTP_HOST} !^www\.
      RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
      
      # Force SSL for /secure.php URIs
      RewriteCond %{HTTPS} off
      RewriteCond %{REQUEST_URI} ^/secure.php
      RewriteRule ^(.*)$ https://www.mysite.com%{REQUEST_URI} [R=301,L]
      

1 个答案:

答案 0 :(得分:0)

HTTP_HOSTREQUEST_URI等服务器变量位于RewriteCond,但不在RewriteRule。如果您需要这些变量,则必须在RewriteCond中捕获它们

RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTP_HOST} (.+)
RewriteRule .* http://www.%1/$0 [R,L]

你不需要在RewriteCond中检查secure.php,你可以在RewriteRule中指定它

RewriteCond %{HTTPS} off
RewriteRule ^/?(secure.php.*) https://www.mysite.com/$1 [R,L]

OT:永远不要在启用301的情况下进行测试,请参阅此回答Tips for debugging .htaccess rewrite rules了解详细信息。