使用.htaccess将非www URL重定向到www

时间:2020-03-05 18:49:43  来源:igfitidea点击:

我正在使用Helicon的ISAPI Rewrite 3,它基本上在IIS中启用.htaccess。我需要将非www网址重定向到www版本,即example.com应该重定向到www.example.com。我从示例中使用了以下规则,但它会影响子域:

RewriteCond %{HTTPS} (on)?
RewriteCond %{HTTP:Host} ^(?!www\.)(.+)$ [NC]
RewriteCond %{REQUEST_URI} (.+)
RewriteRule .? http(?%1s)://www.%2%3 [R=301,L]

这在大多数情况下都有效,但也可以将sub.example.com重定向到www.sub.example.com。如何重写上述规则,以使子域不被重定向?

解决方案

回答

我们不能将RewriteCond调整为仅在example.com上运行吗?

RewriteCond %{HTTP:Host} ^example\.com(.*) [NC]

回答

添加以下RewriteCond:

RewriteCond %{HTTP:Host} ^[^.]+\.[a-z]{2,5}$ [NC]

这样,它将仅将规则应用于nondottedsomething.uptofiveletters,subdomain.domain.com将不符合条件,因此将不会被重写。

我们可以更改[a-z] {2,5},以获得更严格的tld匹配正则表达式,并将所有允许的字符的约束都放置在域名中(因为[^。] +比严格必要的更为宽松)。

总之,在这种情况下,我认为这是没有必要的。

编辑:Sadie在正则表达式上发现了一个缺陷,将其第一部分从[^。]更改为[^。] +

回答

我已经使用urlrewriter.net获得了更多控制权,例如:

<unless header="Host" match="^www\.">
   <if url="^(https?://)[^/]*(.*)$">
     <redirect to="www.domain.tld"/>
   </if>
   <redirect url="^(.*)$" to="http://www.domain.tld"/>
</unless>

回答

为什么(httpd的)vhost文件中没有这样的内容?

ServerName: www.example.com
ServerAlias: example.com

当然,它不会重定向,只会像往常一样进行

回答

Zigdon的想法正确,只是他的正则表达式不太正确。使用

^ example \ .com $

而不是他的建议:

^ example \ .com(。*)

否则,我们不仅会匹配example.com,还将匹配example.comcast.net,example.com.au等。

回答

@Vinko

对于通用方法,我不确定我们为什么选择限制正则表达式中TLD的长度?它不是非常适合未来,并且我不确定它会带来什么好处?实际上,它甚至不是"立即可用的",因为那里至少有一个6个字符的TLD(.museum)无法匹配。

对我来说,似乎没有必要这样做。我们难道不做^ [^。] + \。[^。] \ + $吗? (注意:问号是句子的一部分,而不是正则表达式!)

除此之外,这种方法还有一个更大的问题,那就是:对于不在TLD之下的域,它将失败。这是澳大利亚,英国,日本和许多其他具有层次结构的国家/地区的域名:.co.jp,.co.uk,.com.au等。

我不知道这是否与OP有关,但是如果我们要"全部解决",那是需要注意的事情。

OP尚未明确表示他是否想要通用解决方案还是单个(或者小组)已知域的解决方案。如果是后者,请参阅我关于使用Zigdon方法的其他说明。如果是前者,请考虑本文中的信息,然后继续使用Vinko的方法。

编辑:到目前为止,我遗漏的一件事,或者说可能不是业务选择,还是走另一条路。我们所有的网站都将http://www.domain.com重定向到http://domain.com。 http://no-www.org上的人们提供了一个很好的案例(IMHO),因为这是做到这一点的"正确"方法,但这当然仍然只是一个优先问题。可以肯定的是,为这种重定向编写通用规则要比这种规则容易得多。

回答

@org 0100h是的,问题描述中遗漏了许多变量,所有观点都是正确的,应该在实际实施时加以解决。拟议的正则表达式有利有弊。一方面,它更容易使用,而且面向未来;另一方面,如果要在Host标头中发送example.foobar,我们真的要匹配example.foobar吗?在某些情况下,最终我们将重定向到错误的域。第三种替代方法是修改正则表达式以使用实际域的列表(如果有多个域的话),例如

RewriteCond %{HTTP:Host} (example.com|example.net|example.org) [NC]

(请注意,克里斯将更改%1)

@chrisofspades这不是要替换它,第二个条件可以确保它没有www,而我的则没有。它不会更改%1,%2,%3的值,因为它不存储匹配项(现在,它不使用括号)。