出于业务原因,我RewriteRule
为 Apache 2.2.22 (mod_rewrite) 创建了以下内容:
RewriteRule /site/(\d+)/([^/]+)\.html /site/$2/$1 [R=301,L]
如果给定一个类似这样的 URL:
http://www.example.com/site/0999/document.html
翻译为:
http://www.example.com/site/document/0999.html
这是预期的情况。但是,有些文档的名称仅为数字。因此请考虑以下情况:
http://www.example.com/site/0055/0666.html
翻译为:
http://www.example.com/site/0666/0055.html
这也符合我的RewriteRule
模式,所以我最终得到了“该网页导致过多重定向”来自浏览器的错误。
我研究了很长时间,还没有找到“好”的解决方案。我尝试过的方法:
使用[结尾]标志。不幸的是,在我的 Apache 版本上不可用,也不适用于重定向。
使用
%{ENV:REDIRECT_STATUS}
子句RewriteCond
结束重写过程 (L)。出于某种原因,%{ENV:REDIRECT_STATUS}
我尝试时每次都是空的。如果我的规则匹配,则使用 Header 子句添加响应标头,然后检查该标头(参见:点击此处了解详情)。似乎 a) REDIRECT_addHeader 为空 b) 无法在 301 响应上明确设置标头。
还有另一种选择。我可以为重定向 URL 设置一个查询参数,以表明它来自重定向,但我不喜欢这种解决方案,因为它看起来太黑客了。
有没有办法[END]
在较旧的 Apache 版本中执行该标志所做的事情?比如我的 2.2.22。
答案1
在重定向中添加查询参数是最好的选择。出于各种原因,人们经常这样做。
例如制定如下规则:
RewriteCond %{QUERY_STRING} !redirected
RewriteRule /site/(\d+)/([^/]+)\.html /site/$2/$1?redirected [R=301,L]
现在的情况是重定向到添加了“?redirected”的 URL。因此该规则不会第二次应用。
答案2
[END] 标志在这里不相关,因为您正在提供 301 重定向。正如您链接到的文档所述...
这不适用于由外部重定向导致的新请求。
如果您确实需要执行这种重定向,那么您需要找到其他方法来消除新旧 URL 的歧义。