为什么根据我的 RewriteRule 的位置,我会得到双斜杠?

为什么根据我的 RewriteRule 的位置,我会得到双斜杠?

我正在使用以下代码将所有 www 请求定向到非 www URL:

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

但是,如果我将相同的代码移到我的 VirtualHost 配置中,重写的 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]

但我不明白其中的原因。有人知道为什么吗?

答案1

据我了解,在 .htaccess 文件中,mod_rewrite 在您的规则中处理的字符串与 .htaccess 文件所在的目录相关,因此它不会以 / 开头。

在 VirtualHost 条目中,它处理的字符串相对于服务器的根是绝对的,因此包含 /。

这导致 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]

答案2

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

您可以通过选择性地预先使用斜线来避免这种情况。此外,您还可以在空 VirtualHost 中使用 RedirectMatch 来处理多余的域,这样可以减少一些处理,看起来也更干净。

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

答案3

为了完整性,我把此帖子也包括在内。

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”,而不是在 Apache 配置中使用它。

答案4

我没有时间处理这个问题所以只需将 // 重写为 / :)

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

相关内容