【问题标题】:Possible infinite loop in mod_rewrite?mod_rewrite 中可能存在无限循环?
【发布时间】:2010-10-02 01:55:29
【问题描述】:

我正在修改评论页面的 URL 结构,可以按城市、县、星数和技术人员进行过滤。我想让页面看起来像是静态 HTML 页面,并用连字符替换加号。 我的目标: - 在不修改评论页面的情况下应用新样式 URL,仅修改 htaccess 文件 - 设置从旧式 URL 到新式 URL 的 301 重定向 -将加号转换为连字符

目前评论 URL 如下所示:

domain.com/reviews/?city=City+Name

domain.com/reviews/?city=City+Name&page=2

domain.com/reviews/?county=County+Name

domain.com/reviews/?county=County+Name&page=2

domain.com/reviews/?stars=4

domain.com/reviews/?stars=4&page=2

domain.com/reviews/?tech=Tech+Name

domain.com/reviews/?tech=Tech+Name&page=2

我的目标是让它们看起来像这样(以及 301 旧样式 URL 到新样式 URL):

domain.com/reviews/city/City-Name.html

domain.com/reviews/city/City-Name/page/2.html

domain.com/reviews/county/County-Name.html

domain.com/reviews/county/County-Name/page/2.html

domain.com/reviews/stars/4.html

domain.com/reviews/stars/4/page/2.html

domain.com/reviews/tech/Tech-Name.html

domain.com/reviews/tech/Tech-Name/page/2.html

城市、县和技术名称并不总是包含加号(即波士顿与纽约+纽约),有些名称不止一个加号。目前,这是我必须用新样式 URL 掩盖旧样式 URL(顺便说一句,这很好用):

##FIRST PAGE REVIEWS (ie. reviews/city/city-name.html)
RewriteRule ^reviews/(.*)/(.*)\-(.*)\-(.*)\-(.*)\-(.*)\.html "/reviews/?$1=$2+$3+$4+$5+$6" [NC,L]
RewriteRule ^reviews/(.*)/(.*)\-(.*)\-(.*)\-(.*)\.html "/reviews/?$1=$2+$3+$4+$5" [NC,L]
RewriteRule ^reviews/(.*)/(.*)\-(.*)\-(.*)\.html "/reviews/?$1=$2+$3+$4" [NC,L]
RewriteRule ^reviews/(.*)/(.*)\-(.*)\.html "/reviews/?$1=$2+$3" [NC,L]
RewriteRule ^reviews/(.*)/(.*)\.html "/reviews/?$1=$2" [NC,L]

##PAGINATED REVIEWS (ie. reviews/city/city-name/page/2.html)
RewriteRule ^reviews/(.*)/(.*)\-(.*)\-(.*)\-(.*)\-(.*)/page/(.*)\.html "/reviews/?$1=$2+$3+$4+$5+$6&page=$7" [NC,L]
RewriteRule ^reviews/(.*)/(.*)\-(.*)\-(.*)\-(.*)/page/(.*)\.html "/reviews/?$1=$2+$3+$4+$5&page=$6" [NC,L]
RewriteRule ^reviews/(.*)/(.*)\-(.*)\-(.*)/page/(.*)\.html "/reviews/?$1=$2+$3+$4&page=$5" [NC,L]
RewriteRule ^reviews/(.*)/(.*)\-(.*)/page/(.*)\.html "/reviews/?$1=$2+$3&page=$4" [NC,L]
RewriteRule ^reviews/(.*)/(.*)/page/(.*)\.html "/reviews/?$1=$2&page=$3" [NC,L]

我遇到问题的部分是将旧样式 URL 301 转换为新样式 URL。这是我目前所拥有的:

RewriteCond %{QUERY_STRING} (.*)=(.*) [NC]
RewriteRule ^reviews/(.*) /reviews/%1/%2.html? [NS,R=301,NC]

RewriteCond %{QUERY_STRING} (.*)=(.*)&page=(.*) [NC]
RewriteRule ^reviews/(.*) /reviews/%1/%2/page/%3.html? [NS,R=301,NC]

当我尝试这个 FireFox 时,我给出了“页面没有正确重定向”错误。有什么想法吗?

【问题讨论】:

    标签: .htaccess mod-rewrite http-status-code-301


    【解决方案1】:

    是的,这可能是一个无限循环。使用 THE_REQUEST 代替检查 request line:

    RewriteCond %{THE_REQUEST} ^[A-Z]+\ /[^?\ ]*\?([^=]+)=([^\ ]*)&page=([^\ ]*) [NC]
    RewriteRule ^reviews/ /reviews/%1/%2/page/%3.html? [NS,R=301,NC]
    RewriteCond %{THE_REQUEST} ^[A-Z]+\ /[^?\ ]*\?([^=]+)=([^\ ]*)
    RewriteRule ^reviews/ /reviews/%1/%2.html? [NS,R=301,NC]
    

    请注意,如果参数的数量或顺序与此不同,这将失败。

    【讨论】:

    • 太棒了!谢谢你的工作。唯一的事情是我需要将加号转换为连字符。目前,“/reviews/?city=City+Name”将带您到“/reviews/city/City+Name.html”,它应该是“...City-Name.html”。还有没有办法将所有内容都转换为小写?
    • @Yevgeniy Женя Van Chuchin:虽然这可以通过 mod_rewrite 实现,但它相当复杂,因为您一次只能替换固定数量的出现(例如,参见 stackoverflow.com/questions/3791548/…)。更高级的语言更适合做这种工作。
    • 我可以接受固定金额。 5 次就足够了,这就是我在第一部分所做的(用新样式掩盖旧样式 URL)。
    • @Yevgeniy Женя Van Chuchin:您可以替换任意数量的出现;但一次只有一个固定的数字。然后将重复该步骤。但这很复杂,不推荐。你为什么不使用更高级别的语言来做到这一点?
    • 我认为这一切都可以通过 htaccess 完成,而且由于出现的次数非常有限,我宁愿只用“不推荐”的方式来做——只要它有效。我会使用什么“高级”语言?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-24
    • 1970-01-01
    • 2011-02-24
    • 2010-10-09
    • 2016-03-19
    相关资源
    最近更新 更多