2016-11-29 66 views
1

我遇到了一个我无法解释也不正确的奇怪行为。我需要将每个HTTP请求重定向到HTTPS。我使用下面的代码:RewriteRule更改URL而不是映射到文件

RewriteEngine On 
RewriteBase/

RewriteCond %{HTTPS} off 
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L] 

RewriteRule ^index\.php$ - [L] 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
# The query string in the rewrite is for testing purposes 
RewriteRule (.*) /index.php?url=$1&%{REQUEST_URI}&http=%{HTTPS} [L] 

到目前为止,它的工作原理。然后,我需要一个页面是HTTP,所以我加了一些重写条件:

RewriteEngine On 
RewriteBase/
RewriteCond %{HTTPS} on 
RewriteCond %{REQUEST_URI} ^/not-https 
RewriteRule .* http://%{HTTP_HOST}%{REQUEST_URI} [R=302,L] 

RewriteCond %{HTTPS} off 
RewriteCond %{REQUEST_URI} !^/not-https 
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L] 

RewriteRule ^index\.php$ - [L] 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule (.*) /index.php?url=$1&%{REQUEST_URI}&https=%{HTTPS} [L] 

现在,这里发生了什么。由于某些原因,当访问/not-https页面时,它将重定向到/index.php?url=not-https&/not-https&https=off

以下是GET请求的映射,后跟重定向/显示的URL。

GET: http://example.com/test 
    -> https://example.com/test with proper $_GET 

GET: http://example.com/test.jpg 
    -> https://example.com/test.jpg with no $_GET (file exists) 

GET: https://example.com/not-https 
    -> http://example.com/not-https 
    -> http://example.com/index.php?url=not-https&/not-https&https=off 

我的问题是,为什么在not-https变化所显示的URL(和为此,弄乱我的应用程序)?

回答

1

这是因为REQUEST_URI变量的值在/index.php?...更改为/index.php?...,使条件!^/non-https在第二条规则中成功并使其执行该规则。

更改您的第一条规则这样:

RewriteCond %{HTTPS} on 
RewriteCond %{THE_REQUEST} \s/+not-https [NC] 
RewriteRule^http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE] 

RewriteCond %{HTTPS} off 
RewriteCond %{THE_REQUEST} !\s/+not-https [NC] 
RewriteRule^https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE] 

不像REQUEST_URI变量THE_REQUEST不改变它的其他内部重写执行后的值。

+1

非常感谢你,解决了一切。我的猜测是'REQUEST_URI'在某种程度上发生了变化,但我在文档中找不到任何东西。另外,我觉得很难调试'.htaccess'文件... –