【问题标题】:RewriteRule violates while switching from https to http从 https 切换到 http 时 RewriteRule 违反
【发布时间】:2012-09-06 05:14:07
【问题描述】:

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

注意: 在 localhost 上一切正常,问题出在服务器上 UPDATE

这是我的website ,目前所有链接都按照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

注意:即使鼠标悬停在页面上也会显示重写链接

下面是.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),那么它会报错?
  • [NC,L] 与所有 RewriteRule 一起写是一种好习惯吗?
  • 我应该在什么时候写[QSA]

更新

根据所有答案的建议,更改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://www.charityrummage.com/about,关于我们页面的链接不应该在 http 中吗??
  • 是的鼠标悬停显示右链接,但如果你点击这个然后看到链接?
  • QSA 仅在您更改查询字符串(通过在替换中使用 ?)并且您想要附加旧字符串时才有意义。不要将 NC,L 附加到每个规则中。如果您希望它不区分大小写,请使用 NC。在 htaccess 中,使用 L 会导致当前轮次处理以当前替换结束——要么你的 htaccess 依赖于此,要么不依赖。

标签: php apache .htaccess mod-rewrite https


【解决方案1】:

我想这可能对你有帮助

.htaccess redirect https to http not working

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

http://httpd.apache.org/docs/current/rewrite/flags.html

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

【讨论】:

  • 不,使用端口是个坏主意。而不是这两个条件一起使用:RewriteCond %{SERVER_PORT} !^443$ [OR] RewriteCond %{HTTPS} off
【解决方案2】:

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

您不能在 .htaccess 中执行此操作,但在 http.conf &lt;VirtualHost&gt; 部分中,您可以使用 ServerNameServerAlias 指令来完成此操作。

【讨论】:

    【解决方案3】:

    您对 /about 的困惑是由于重定向到 %{REQUEST_URI},在您进行替换时不会更改。捕获 URI 并使用 $1 如果您真的不想要该 URI,因为它在这一轮重写处理中开始。

    【讨论】:

      【解决方案4】:

      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


      回答您的其他问题

      如果我改变rewrite URL的大小写会报错?

      这是因为您的 [NC] 不在 .htaccess 的 HTTPS 部分的重写条件中

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


      用所有 RewriteRule 编写 [NC,L] 是一种好习惯吗?

      不,这取决于你想做什么[NC] 说不匹配这个规则的大小写,如果你不想匹配那个 规则(或 条件) 然后添加它。

      [NC] 不匹配表示site.com/login.php = sYte.cOm/LoGin.PHP

      [L] 表示如果这是真的,停止处理一切


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

      当您有 ?在您的替换中,您想将旧字符串附加到新 URL

      考虑以下规则:

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

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

      如果您想保留任何额外的 get 参数,请使用 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,这不是您想要做的,您要将它们发送到 /login。 p>

      您是否尝试过使用(如我的 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]
      

      【讨论】:

      • +1 感谢您的回复。请您在HTTPS suggestion点上描述更多信息
      • 即使我用 RewriteCond %{REQUEST_URI} (/login|/do_login.php) RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,NC] 更改了 [OR] 行,但 website.com/ Login 仍然出错。
      • 你想要的是 NC,而不是规则
      • 我已经更新了我的代码。根据您的建议已修复了许多问题,现在只有 1 个问题。请看看我的更新。
      • 我试过你给出的解决方案,但它给出了 这个网页有一个重定向循环 错误。第二件事:https 上要显示的页面很少(添加在 | 条件中)所以https://%{HTTP_HOST}/login 将无济于事。
      猜你喜欢
      • 2017-02-18
      • 1970-01-01
      • 1970-01-01
      • 2012-12-28
      • 2014-06-08
      • 1970-01-01
      • 2017-05-09
      • 2011-12-11
      • 2012-09-08
      相关资源
      最近更新 更多