【问题标题】:Removing 'index.html' from url and adding 'www' with one single 301 redirect从 url 中删除 'index.html' 并使用一个 301 重定向添加 'www'
【发布时间】:2011-08-28 22:20:00
【问题描述】:

为了从网址中删除index.htmlindex.htm,我在.htaccess 中使用以下内容

RewriteCond %{REQUEST_URI} /index\.html?$ [NC]
RewriteRule ^(.*)index\.html?$ "/$1" [NC,R=301,NE,L]

这行得通!(有关此问题末尾的标志的更多信息 *)

然后为了在网址中添加www,我在.htaccess中使用以下内容

RewriteCond %{HTTP_HOST} !^www\.mydomain\.com$ [NC]
RewriteRule ^(.*)$ "http://www.mydomain.com/$1" [R=301,NE,L]

这也有效!

这里的问题是在以下情况下如何避免上述规则造成的双重重定向:

  1. 浏览器要求http://mydomain.com/path/index.html
  2. 服务器将301 标头发送到重定向浏览器到http://mydomain.com/path/
  3. 然后浏览器请求http://mydomain.com/path/
  4. 现在服务器将301标头发送到重定向浏览器到http://www.mydomain.com/path/

这显然不是很聪明,因为问http://mydomain.com/path/index.html 的可怜用户会被双重重定向,他会觉得页面太慢了。此外,Googlebot 可能会停止跟踪导致双重重定向的链接原因(我不确定最后一个,我不想对此进行讨论,这只是另一个可能的问题。)

谢谢!


*可能感兴趣的人:

  • NC 也用于重定向 大写文件即INDEX.HTML / InDeX.HtM
  • 使用NE 为了避免双重网址编码,我避免 http://.../index.html?hello=ba%20be 被重定向到 http://.../index.html?hello=ba%2520be
  • QSA 用于重定向 也查询,即 http://.../index.html?hello=babehttp://.../?hello=babe(不需要感谢anubhava answer

【问题讨论】:

  • Answer in near-duplicate。公平地说,另一个问题并没有要求每个规则都使用一个重定向,但无论如何答案都是正确的。
  • @Cori Xii:我在问我之前阅读了那个问题/答案,那里的规则和我的一样,但正如你所说,这个问题是关于如何避免双重重定向,另一个问题是不介意进行双重重定向。
  • 另一个 question 不介意,但接受的 answer 无论如何都会满足您的要求,不是吗?
  • @Core Xii:我测试了你建议的答案stackoverflow.com/questions/5607001/…,它适用于那个问题,但它仍然执行双301重定向,所以它不能解决我的问题。

标签: regex apache .htaccess redirect mod-rewrite


【解决方案1】:

为避免双重重定向,在 .htaccess 文件中设置另一个规则,同时满足这两个条件:

Options +FollowSymlinks -MultiViews
RewriteEngine on

RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{REQUEST_URI} ^(.*/)index\.html$ [NC]
RewriteRule . http://www.%{HTTP_HOST}%1 [R=301,NE,L]

RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule . http://www.%{HTTP_HOST}%{REQUEST_URI} [NE,R=301,L]

RewriteCond %{REQUEST_URI} ^(.*/)index\.html$ [NC]
RewriteRule . %1 [R=301,NE,L]

因此,如果输入 URL 是 http://mydomain.com/path/index.html,那么这里的第一条规则中的两个条件都得到满足,并且将有 1 个单一重定向 (301) 到 http://www.mydomain.com/path/

我也相信QSA 标志在上面并不是真正需要的,因为您不是 操纵查询字符串。

【讨论】:

  • 所以基本上我需要将两个 RewriteRule/RewriteCond 合并为一个。有趣的是,我认为会有更简单的方法。顺便说一句,我认为/?(.*/?) 中毫无意义,因为在您拥有匹配任何字符的.* 之前。关于QSA我觉得你说的对,没用,我更新了问题。
  • 我还在 index.html 重写规则之前的问题中添加了RewriteCond %{REQUEST_URI} /index\.html?$ [NC],否则http://.../pathindex.htmlpathindex.html 之间没有斜线)也将被重定向到http://.../path
  • @Marco Demaio:我在上面的答案中做了一些小的修改,以解决(.*/?) 的一个问题。早些时候,如果您有一个 /myindex.html 的 URI,它也被重定向到 /my,我们当然不会让这种情况发生,所以现在我从 %{REQUEST_URI} 变量中捕获带有前导斜杠的 URI,并在 RHS 上使用它。请再试 1 次。
  • 我认为你在RewriteCond %{REQUEST_URI} ^(.*/)index.html$ [NC] 中忘记了一个斜线这个条件也满足http://.../path/index0html 因为正则表达式中的. 匹配任何字符,它应该是RewriteCond %{REQUEST_URI} ^(.*/)index\.html$ [NC] 无论如何我明白了你的想法第一段的解决方案:...have another rule in .htaccess file that meets both conditions
  • 这个例子对我来说的问题是http://example.com/index.html重定向到http://example.com/而不是http://www.example.com/,这样可以同时解决这两个问题。
【解决方案2】:

更好的解决方案是将 index.html 规则放在 www 规则之前,并在 index.html 规则内将 www 前缀添加到目标 url。这样,寻找 http://domain.com/index.html 的人会被 FIRST 规则发送到 http://www.domain.com/。第二个 (www) 规则仅在 index AND www 缺失时才适用,这又是一个重定向。

【讨论】:

【解决方案3】:

从先前的规则中删除L 标志? L forces the rule parsing to stop(当规则匹配时),因此发送第一个重写的 URL 而不应用第二个规则。

规则从上到下依次应用,如果匹配规则的条件和模式,则每次重写 URL再次

RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301]

RewriteRule ^(.*/)index\.html?$ $1 [NC,QSA,R=301,NE,L]

因此上面会先添加www,然后删除index.html?,然后再发送新的URL; 所有规则的单一重定向。

【讨论】:

  • 对不起,它不起作用!我之前尝试删除L,现在我也再次尝试以防万一。如果我在用户转到http://domain.com/index.html 时删除了L¸,他会重定向到http://domain.com/http://www.domain.com/(并且我没有错误地写两次url,这正是服务器发送的301标头)
  • 我也无法让你的规则发挥作用,而且我已经厌倦了与这件事搏斗。也许它不喜欢被放在子目录中,我不知道。
  • 既然你说我的规则不起作用,你可以试试stackoverflow.com/questions/5607001/…问题的规则,我还是想避免双重重定向。
  • 好的,我让它再次工作,可能是一些浏览器缓存问题。更新了我的答案。规则现在几乎有效,除了一种情况:http://www.comain.com/index.html 出于某种原因没有删除index.html
猜你喜欢
  • 2017-01-16
  • 2011-09-02
  • 2017-04-22
  • 2013-01-06
  • 2013-06-28
  • 2017-07-27
  • 1970-01-01
  • 1970-01-01
  • 2016-12-26
相关资源
最近更新 更多