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

使用.htaccess将非www URL重定向到www,.htaccess,isapi-rewrite,.htaccess,Isapi Rewrite,我正在使用,它基本上在IIS中启用.htaccess。我需要将非www URL重定向到www版本,即example.com应重定向到www.example.com。我使用了示例中的以下规则,但它会影响子域: RewriteCond %{HTTPS} (on)? RewriteCond %{HTTP:Host} ^(?!www\.)(.+)$ [NC] RewriteCond %{REQUEST_URI} (.+) RewriteRule .? http(?%1s)://www.%2%3 [R=3

我正在使用,它基本上在IIS中启用.htaccess。我需要将非www URL重定向到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。我如何重写上述规则,使子域不被重定向?

您能否将“重写条件”调整为仅在example.com上运行

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

附加以下重写条件:

RewriteCond %{HTTP:Host} ^[^.]+\.[a-z]{2,5}$ [NC]
这样,它只会将规则应用于nondottedsomething.uptofIveletter,正如您所看到的,subdomain.domain.com将不符合条件,因此不会被重写

您可以将[a-z]{2,5}更改为更严格的tld匹配正则表达式,并将所有允许的字符限制放在域名中(因为[^.]+的权限比严格必要的权限更大)

总而言之,我认为在这种情况下没有必要这样做


编辑:sadie发现了正则表达式上的一个缺陷,将它的第一部分从[^.]更改为[^.]+

我通过以下方式获得了更多的控制:

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

为什么不在vhost(httpd)文件中包含类似的内容


当然,这不会改变方向,这会像平常一样继续下去,齐格登的想法是正确的,只是他的正则表达式不太正确。使用

^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的方法


编辑:到目前为止,我遗漏了一件事,从商业角度看,这可能是你的一个选择,也可能不是,那就是走另一条路。我们所有的网站都重定向到。该公司的员工提出了一个很好的理由(IMHO),认为这是一种“正确”的方式,但这当然只是偏好的问题。但有一点是肯定的,为这种重定向编写通用规则要比编写此规则容易得多。

@org 0100h是的,有许多变量没有在问题的描述中给出,您的所有观点都是有效的,应该在实际实现时加以解决。你提议的正则表达式既有优点也有缺点。一方面,它更简单,也更能证明未来,另一方面,如果在主机头中发送example.foobar,您真的想匹配它吗?当您最终重定向到错误的域时,可能会出现一些边缘情况。第三种选择是修改正则表达式以使用实际域的列表(如果不止一个),如

RewriteCond %{HTTP:Host} (example.com|example.net|example.org) [NC]
(请注意,一个将改变%1)


@当然,这并不是要取代它,你的第二个条件确保它没有www,而我的则没有。它不会更改%1、%2、%3的值,因为它不存储匹配项(注意,它不使用括号)。

它应该是^example\.com$。在任何情况下,我的印象是chris想要一个通用的解决方案,而不是一个单一域的解决方案。你是说我应该用你的条件替换第2行,还是将你的条件添加到一个新行?将其添加到新行会影响使用%1、%2和%3的重写规则吗?
RewriteCond %{HTTP:Host} (example.com|example.net|example.org) [NC]