为什么根据我的RewriteRule的位置得到一个双尾斜杠?

我正在使用以下代码将所有www请求指向非wwwurl:

RewriteEngine On RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC] RewriteRule ^(.*)$ http://example.com/$1 [R=301,L] 

这在我的网站根目录下的.htaccess文件里面工作的很好。
例如,
www.example.com – > example.com/
www.example.com/ – > example.com/
www.example.com/other_page – > example.com/other_page

但是,如果将相同的代码移到我的VirtualHostconfiguration中,则重写的URL将包含一个双尾斜杠。
www.example.com – > example.com//
www.example.com/ – > example.com//
www.example.com/other_page – > example.com//other_page

我通过从重写规则中删除斜线来修复它:

 RewriteEngine On RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC] RewriteRule ^(.*)$ http://example.com$1 [R=301,L] 

但是我不明白这个原因。 任何人知道为什么

据我了解,在.htaccess文件中,mod_rewrite在你的规则中处理的string是相对于.htaccess文件所在的目录而言的,所以它在开始时不会有/。

在VirtualHost条目中,它处理的string对于服务器的根是绝对的,因此包括/。

这使得mod_rewrite的工作方式有了细微的差别。

这里是一个有类似问题的人,解决办法:

http://forum.modrewrite.com/viewtopic.php?p=56322&sid=77f72967f59200b5b5de174440234c3a

这应该在两种情况下工作,假设我记得我的转义正确:

 RewriteEngine On RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC] RewriteRule ^\/?(.*?)$ http://example.com/$1 [R=301,L] 

发生这种情况是因为您正在使用(.*)捕获初始斜线,然后在新位置/$1之前应用另一个斜线。 之前没有发生过,因为mod_rewrite在每个目录上下文中运行时的行为略有不同,而不是每个服务器上下文。

您可以通过select性地预先设定斜线来避免这种情况。 另外,你可以在剩余域名的空虚拟主机中使用RedirectMatch,这样可以减less处理,并且看起来更干净。

<VirtualHost *>
ServerName example.com
ServerAlias other.example.com
..
RedirectMatch permanent ^/?(.*) http://example.com/$1
</VirtualHost>

我包括这个职位的完整性。

Apache文档解释了为什么这种行为发生得很好,是“RewriteBase”指令存在的原因。

只需在你的.htaccess文件中包含'RewriteBase'指令就可以实现你想要的结果。

例:

 RewriteEngine On RewriteBase / RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC] RewriteRule ^(.*)$ http://example.com/$1 [R=301,L] 

从Apache 2.2 mod_rewrite文档:

RewriteBase指令显式地设置每个目录重写的基本URL。

我的经验法则是几乎总是在.htaccess文件中使用“RewriteBase”,而不是在Apacheconfiguration中使用它。

我没有时间来处理这个问题,所以只需重写// / 🙂

 RewriteCond %{THE_REQUEST} // RewriteRule ^(.*)$ http://domain.com [R=301,L]