从https转换到http时,RewriteRule违反

我在我的.htaccess文件中写了很多RewriteRule ,但是当我从https切换到http页面时发生问题; 它不遵循这些规则

注意:一切在本地主机上工作正常,问题是在服务器<—- 更新

这里是我的网站 ,目前所有的链接都显示为RewriteRule *

例如关于我们的页面链接显示为

 http://www.mywebsite.com/about 

如果我在login page (这是在https ),并点击关于我们的网页,然后变成下面。

 http://www.mywebsite.com/about?slug=about_us 

或者如果我点击左面板上的任何类别,那么它就是

 http://www.mywebsite.com/auction/category/1?cid=1 

注:即使鼠标hover在页面上显示重写链接

下面是带有所需信息的.htaccess文件。

 IndexIgnore * RewriteEngine on Options +FollowSymLinks RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^auction/category/([0-9]+)/?$ bids.php?cid=$1 [NC] RewriteRule ^login/?$ login.php [NC] RewriteRule ^register/?$ register.php [NC] RewriteRule ^logout/?$ logout.php [NC] # static pages RewriteRule ^about/?$ page.php?slug=about_us [NC] # Rewrite to https RewriteCond %{SERVER_PORT} !^443$ [OR] RewriteCond %{HTTPS} off RewriteCond %{REQUEST_URI} /login [OR] RewriteCond %{REQUEST_URI} /do_login.php RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,NC,L,QSA] # don't do anything for images/css/js (leave protocol as is) RewriteRule \.(gif|jpe?g|png|ico|css|js)$ - [NC,L] # traffic to http:// except some pages RewriteCond %{SERVER_PORT} ^443$ [OR] RewriteCond %{HTTPS} on RewriteCond %{REQUEST_URI} !(/login|/do_login.php) RewriteRule ^(.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,NC,L,QSA] 

注意: Here是完整的.htaccess文件

请告诉我我错在哪里?

我也有一些更多的困惑

  • 如果我改变重写URL( login或lOgin或logiN )的情况下,它会给出错误?
  • 用所有的RewriteRule[NC,L]是不是很好?
  • 到底什么时候我应该写[QSA]

UPDATE

经过所有答案的build议后RewriteRule几乎可以解决所有问题,但是现在还有最后一个问题。

  • /login URL总是变成/login.php

下面是我更新的.htaccess

 IndexIgnore * Options -MultiViews Options +FollowSymLinks #mod_rewrite RewriteEngine on RewriteBase / # Rewrite www to non www RewriteCond %{HTTP_HOST} ^www.%{HTTP_HOST} [NC] RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [R=301,L] # minimize the css on all http:// pages <IfModule mod_rewrite.c> RewriteCond %{HTTPS} off RewriteRule ^(.*).css$ /csszip.php?file=$1.css [L] </IfModule> #switch over http to https # Rewrite to https RewriteCond %{SERVER_PORT} !^443$ [OR] RewriteCond %{HTTPS} off RewriteCond %{REQUEST_URI} (/login|/do_login)\.php [NC] RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] # don't do anything for images/css/js (leave protocol as is) RewriteRule \.(gif|jpe?g|png|ico|css|js)$ - [NC,L] # traffic to http:// except some pages RewriteCond %{SERVER_PORT} ^443$ [OR] RewriteCond %{HTTPS} on RewriteCond %{REQUEST_URI} !(/login|/do_login)\.php [NC] RewriteRule ^(.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^login/?$ login.php [NC] RewriteRule ^register/?$ register.php [NC] # ...many other rules...with [NC] falg RewriteRule ^auction/category/([^/.]+)/?$ bids.php?cid=$1 [NC] RewriteRule ^about/?$ page.php?slug=about_us [NC] # ...many more rules.... with [NC] flag 

HTTPS建议

对于您的HTTPS问题,我将在端口或HTTPS上匹配,因为已知的与HTTPS标记有关的apache问题。

为了覆盖这两个匹配(如编辑答案中所示)

 RewriteCond %{SERVER_PORT} !^443$ [OR] RewriteCond %{HTTPS} != on ##REWRITE RULE RewriteCond %{SERVER_PORT} ^443$ [OR] RewriteCond %{HTTPS} = on ##REWRITE RULE 

有效的一点也是%{REQUEST_URI}不受任何替换的影响。

您目前使用的方式,如果有任何规则匹配,您会将它们发送到原始URL(在任何替换开始之前)。

如果你想采取后的URL和替换和匹配使用$1


解答您的其他问题

如果我改变重写URL的情况下,它会给出错误?

这是因为您的[NC]不在您的.htaccess的HTTPS部分的重写cond上

你匹配RewriteCond %{REQUEST_URI} /login [OR]这只是寻找小写登录,如果你想接受大写登录追加NC。


用所有的RewriteRule写[NC,L]是不是很好?

不,这取决于你想做什么[NC]说不符合这个规则的情况下,如果你不想匹配该规则 (或条件 )的情况下,然后添加它。

不匹配[NC]的情况意味着site.com/login.php = sYte.cOm/LoGin.PHP

[L]意味着如果这是真的,停止处理一切


到底什么时候我应该写[QSA]?

QSA适用于你有? 在你的替换,你想追加旧旧的字符串到新的URL

考虑以下规则:

 RewriteRule /pages/(.+) /page.php?page=$1 [QSA] 

使用[QSA]标志, /pages/123?one=two的请求将被映射到/page.php?page=123&one=two 。 没有[QSA]标志,相同的请求将被映射到/page.php?page=123 – 也就是说,现有的查询字符串将被丢弃

如果您想保留任何额外的获取参数, 使用QSA。


还有一个问题

/ login URL总是变成/login.php

发生这种情况的唯一方法是,如果你的代码中有一个重定向[R=301] ,那么我可以看到的唯一的地方就是这个部分:

 # Rewrite to https RewriteCond %{SERVER_PORT} !^443$ [OR] RewriteCond %{HTTPS} != on RewriteCond %{REQUEST_URI} (/login|/do_login)\.php [NC] RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] 

只会匹配以下网址

.php,/login.php,/do_login.php

我相信这个罪魁祸首就是我在第一个回复中用%{REQUEST_URI}

你的代码基本上说,如果满足这些条件,把它们发送到https:// theurltheywentto ,这不是你想要做的,你想要发送到/登录。

你有没有尝试过使用(如在我的https部分中提到的)

 RewriteRule ^(.*) https://%{HTTP_HOST}/login [R=301,L] 

或者也许(如果你有/ do_login)和其他选项

 RewriteRule ^(.*).php https://%{HTTP_HOST}/$1 [R=301,L] 

test.com/do_login.php将成为https://test.com/do_login

你如何尝试:

 # Rewrite to https RewriteCond %{REQUEST_URI} (/login|/do_login)\.php [NC] RewriteCond %{HTTPS} != on RewriteRule ^(.*)\.php https://%{HTTP_HOST}/$1 [R=301,L] 

我想这可能是你的帮助

.htaccess重定向https到http不能正常工作

对于最后一个问题,这可能是你的帮助

http://httpd.apache.org/docs/current/rewrite/flags.html&#x548C;

http://www.addedbytes.com/download/mod_rewrite-cheat-sheet-v2/png/

编辑:你可以尝试使用

 RewriteCond %{SERVER_PORT} ^443$ RewriteCond %{SERVER_PORT} !^443$ 

代替

 RewriteCond %{HTTPS} on [NC] RewriteCond %{HTTPS} off [NC] 

详细信息

请看这个链接,有人有类似的问题。 请看帖子的第二个回复

http://www.webmasterworld.com/apache/3228459.htm

你可以通过创建域别名来解决这个问题

你不能在.htaccess做,但在http.conf <VirtualHost>部分,你可以使用serverNameserverAlias指令来完成这个。

您对/ about的疑惑是由于重定向到%{REQUEST_URI},而您在进行替换时并未改变。 捕获URI并使用$ 1,如果你真的不需要这个URI,因为它开始了这一轮的重写处理。