【问题标题】:How to avoid chain redirections using mod_rewrite?如何使用 mod_rewrite 避免链式重定向?
【发布时间】:2012-12-28 20:40:22
【问题描述】:

基本上,我在我的网站上工作是为了对 SEO 友好。我想实现以下目标:

  • 将网址重写为漂亮的网址
  • 删除多个斜杠(例如,example.com/////something///example.com/something/
  • 将 www 版本重定向到非 www 版本。
  • 从所有 url 中隐藏 index.php 文件
  • 从旧网址(/?id=something/ 重定向到新网址 /something/

我想出了这个.htaccess 代码:

RewriteCond %{THE_REQUEST} //
RewriteRule .* $0 [R=301]

RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteCond %{QUERY_STRING} ^id=([a-z0-9\/-]+)
RewriteRule ^(.*)$ http://example.com/%1? [R=301]

RewriteRule ^index.php(.*)$ /$1 [R=301]
RewriteRule ^([a-z0-9\/-]+)$ /?id=$1 [L] 

...虽然它正在工作,但它有一个副作用:链重定向,例如。 example.com/?id=something////// -> example.com/something////// -> example.com/something/

那么有没有办法重写或修改此代码,使其只重定向一次到首选版本的 url?

【问题讨论】:

  • 首先将 L 标志添加到所有重写规则。然后,让我们知道会发生什么。
  • @felipe:我已将 L 标志添加到所有、任何单个并更改了这些组合中的顺序,但没有成功。

标签: apache .htaccess mod-rewrite redirect


【解决方案1】:

试图解释你想要什么,让我们看看你问题中的规则:

.1 无法理解这样做的目的:

RewriteCond %{THE_REQUEST} //
RewriteRule .* $0 [R=301]

.2 您问题中的此规则集删除了www 并将查询字符串?id=val 转换为/val,但仅当传入的URI 具有www 并且存在查询字符串,因为这两个条件都必须是遇见:

RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteCond %{QUERY_STRING} ^id=([a-z0-9\/-]+)
RewriteRule ^(.*)$ http://example.com/%1? [R=301]

.3 这条规则

RewriteRule ^index.php(.*)$ /$1 [R=301]

隐藏index.php,但仅当它位于根目录时。示例:

http://www.example.com/index.php?id=val

在子目录中时不起作用。示例:

http://www.example.com/folder/index.php?id=val

.4 无法理解这样做的目的:

RewriteRule ^([a-z0-9\/-]+)$ /?id=$1 [L]

我建议改为:

RewriteEngine On
RewriteBase /

#Redirects all www to non-www
RewriteCond %{HTTP_HOST} www\.example\.com$ [NC]
RewriteRule ^(.*)/?$ http://example.com/$1 [R=301,L]

#Hides "index.php" keeping the query if present
RewriteRule ^(.*)/index\.php$ $1/ [R=301,QSA,L]

#Converts query string `?id=val` to `/val`
RewriteCond %{QUERY_STRING} id=([^/]+)
RewriteRule .* /%1? [R=301,L]

【讨论】:

    【解决方案2】:

    请记住,蜘蛛会在几个月后“适应”正确的新结构,而且问题最终可能比最初看起来要严重得多。您可以保留所有 .htaccess 代码,知道它总是在那里纠正任何“旧”引用,但实际上几乎不会真正使用。

    我从来没有找到一种简单的方法来避免在“修复”某个 URL 以使其处于某种规范形式时多次往返客户端。 mod_rewrite 似乎更关注“本地”重定向情况,客户端不知道它返回的内容来自与 URL 所暗示的不完全匹配的文件结构。

    可能在本地保存所有 URL 模块,然后通过在新创建的“环境”变量中设置所有内容,只触发一次到客户端的往返,该客户端一次提供所有 URL 更正然后最后问基本上“有什么改变吗?”然而,这样做非常冗长,相当尴尬,而且很容易出错,并且从未成为“推荐的技术”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-08
      • 2011-11-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多