Apache 重写规则互相破坏吗?

Apache 重写规则互相破坏吗?

我有这样的规则:

RewriteCond %{REQUEST_URI} ^/(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/.*$
RewriteCond %{REQUEST_URI} !^/guide/(.*)$
RewriteRule ^(.*)$ /home/neezer/public-html/domain.com/guide/$1 [L]

它本身就很好用。本质上,我有一堆目录,里面有很多文件,我想把它们保存在“/guide”文件夹中,但出于 SEO 原因,我希望它们出现在 Web 根目录中。

此规则有效,但不幸的是,原始 URL 仍然有效(带有“/guide”)。我想将 URL 中带有“/guide”的 301 重定向到不带有“/guide”的 URL,而无需实际移动服务器上的文件。

我尝试添加这条规则:

RewriteCond %{REQUEST_URI} ^/guide/(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/.*$
RewriteRule ^guide/(.*)$ http://www.domain.com/$1 [R=301,L]

... 但这完全违反了我的第一条规则。

对我可能做错的事情有什么想法吗?如果您需要我提供任何其他信息来帮助我解决此问题,请告诉我。


编辑:根据马修斯的建议,我将规则改为这样(反映了我想要的行为):

RewriteRule ^guide/(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/(.*)$ http://www.domain.com/$1-apartments/$2 [R=301,L]
RewriteRule ^(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/(.*)$ /home/neezer/public-html/domain.com/guide/$1-apartments/$2 [L]

然而,规则仍然相互冲突,只是这次的方式不同。尝试访问受第二条规则管辖的页面(以及第一条规则正确重定向到的页面)时,Safari 出现以下错误:

尝试打开“时发生过多重定向http://www.domain.com/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php”。如果您打开一个页面,而该页面被重定向打开另一个页面,然后该页面又被重定向打开原始页面,则可能会发生这种情况。

有什么建议么?


进一步编辑:

看起来这些规则正在自我循环。以下是重写日志的摘录:

init rewrite engine with requested uri /manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php
pass through /manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php
[perdir /home/neezer/public-html/domain.com/] rewrite 'manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php' -> '/home/neezer/public-html/domain.com/guide/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php'

[perdir /home/neezer/public-html/domain.com/] strip document_root prefix: /home/neezer/public-html/domain.com/guide/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php -> /guide/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php
[perdir /home/neezer/public-html/domain.com/] internal redirect with /guide/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php [INTERNAL REDIRECT]
init rewrite engine with requested uri /guide/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php

pass through /guide/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php
[perdir /home/neezer/public-html/domain.com/] rewrite 'guide/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php' -> 'http://www.domain.com/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php'
[perdir /home/neezer/public-html/domain.com/] explicitly forcing redirect with http://www.domain.com/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php
[perdir /home/neezer/public-html/domain.com/] escaping http://www.domain.com/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php for redirect
[perdir /home/neezer/public-html/domain.com/] redirect to http://www.domain.com/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php [REDIRECT/301]

我认为问题出在中间部分(我用换行符将其分开)。Apache 重写到本地路径(使用/home/neezer/...)后,似乎会发出另一个请求,其中删除了文档根目录,当然包括/guide,然后过滤第一条规则,最终过滤第二条规则,如此反复,直到无穷。

我如何告诉它在第一条规则之后停止?添加[L]似乎没有效果。

答案1

我不确定你为什么要使用 RewriteConds。在我看来,你可以将所有内容直接放入 RewriteRules 中。看起来你的问题源于你重定向了与 Request_URI 匹配的所有内容。如果你在 RewriteRule 本身中进行匹配,则重写的规则将不再匹配下一个规则。

你可能想尝试以下方法:

RewriteRule ^guide/(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/(.*)$ http://www.domain.com/$2 [R=301]
RewriteRule ^(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/(.*)$ /home/neezer/public-html/domain.com/guide/$2 

您可能需要调整这些,因为我不了解您要完成的所有任务。例如,下面的 RewriteCond 似乎是多余的,所以我将其省略了。如果您确实想重写指南目录下的所有内容,则必须将其重新合并。

RewriteCond %{REQUEST_URI} !^/guide/(.*)$

编辑
在我的服务器上进行一些快速测试之后,我能够使这些规则发挥作用,但不能在每个目录上下文中发挥作用(即不在 .htaccess 中或在 内部<Directory></Directory>)。

我没有测试过这个,但您可以通过使用第二条规则设置环境变量,然后在第一条规则上对其进行测试来解决这个问题。

RewriteCond %{ENV:REDIRECT} !^NO$
RewriteRule ^guide/(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/(.*)$ http://www.domain.com/$2 [R=301]
RewriteRule ^(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/(.*)$  [E=REDIRECT:NO]

答案2

我无法找到解决该无限循环的任何方法,因此我将文件移动到了一个名为“邻居”的新文件夹并使用了以下规则:

RewriteRule ^guide/(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/(.*)$ http://www.domain.com/$1-apartments/$2 [R=301,L]
RewriteRule ^(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/(.*)$ /home/neezer/public-html/domain.com/neighborhoods/$1-apartments/$2 [L]

不太理想,因为现在我有两个文件夹(我还有其他文件需要按照指南来提供),但它确实解决了我的 SEO 问题。

相关内容