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

发布于 2024-07-04 03:27:13 字数 501 浏览 12 评论 0原文

我正在使用 Helicon 的 ISAPI Rewrite 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。 如何重写上述规则以使子域不会被重定向?

I'm using Helicon's ISAPI Rewrite 3, which basically enables .htaccess in IIS. I need to redirect a non-www URL to the www version, i.e. example.com should redirect to www.example.com. I used the following rule from the examples but it affects subdomains:

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

This works for most part, but is also redirect sub.example.com to www.sub.example.com. How can I rewrite the above rule so that subdomains do not get redirected?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

乄_柒ぐ汐 2024-07-11 03:27:13

不能将RewriteCond调整为仅在example.com上操作吗?

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

Can't you adjust the RewriteCond to only operate on example.com?

RewriteCond %{HTTP:Host} ^example\.com(.*) [NC]
寄居人 2024-07-11 03:27:13

为什么你不在你的 vhost (httpd) 文件中添加类似的内容呢?

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

当然,这不会重定向,只会照常进行

Why dont you just have something like this in your vhost (of httpd) file?

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

Of course that wont re-direct, that will just carry on as normal

近箐 2024-07-11 03:27:13

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

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

I've gotten more control using urlrewriter.net, something like:

<unless header="Host" match="^www\.">
   <if url="^(https?://)[^/]*(.*)$">
     <redirect to="$1www.domain.tld$2"/>
   </if>
   <redirect url="^(.*)$" to="http://www.domain.tld$1"/>
</unless>
白鸥掠海 2024-07-11 03:27:13

附加以下 RewriteCond:

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

这样,它只会将规则应用于 nondottedsomething.upto Fiveletters,如您所见,subdomain.domain.com 将不匹配条件,因此不会被重写。

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

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

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

Append the following RewriteCond:

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

That way it'll only apply the rule to nondottedsomething.uptofiveletters as you can see, subdomain.domain.com will not match the condition and thus will not be rewritten.

You can change [a-z]{2,5} for a stricter tld matching regex, as well as placing all the constraints for allowed chars in domain names (as [^.]+ is more permissive than strictly necessary).

All in all I think in this case that wouldn't be necessary.

EDIT: sadie spotted a flaw on the regex, changed the first part of it from [^.] to [^.]+

回忆躺在深渊里 2024-07-11 03:27:13

@Vinko

对于您的通用方法,我不确定您为什么选择限制正则表达式中 TLD 的长度? 它不太面向未来,我不确定它能提供什么好处? 实际上,它甚至不是“现在证明”的,因为至少有一个 6 字符 TLD (.museum) 无法匹配。

我看来没有必要这样做。 你不能直接做^[^.]+\.[^.]\+$吗? (注意:问号是句子的一部分,而不是正则表达式!)

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

我不知道这是否是OP关心的问题,但如果您想要“修复所有问题”的答案,则需要注意这一点。

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

编辑:到目前为止,我遗漏的一件事是走另一条路,这可能是也可能不是您商业上的选择。 我们所有的网站都将 http://www.domain.com 重定向到 http://domain.comhttp://no-www.org 的人们为此提出了一个很好的案例(恕我直言) “正确”的方式来做到这一点,但这仍然只是一个偏好问题。 但有一件事是肯定的,为这种重定向编写通用规则比这个要容易得多。

@Vinko

For your generic approach, I'm not sure why you chose to limit the length of the TLD in your regex? It's not very future-proof, and I'm unsure what benefit it's providing? It's actually not even "now-proof" because there's at least one 6-character TLD out there (.museum) which won't be matched.

It seems unnecessary to me to do this. Couldn't you just do ^[^.]+\.[^.]\+$? (note: the question-mark is part of the sentence, not the regex!)

All that aside, there is a bigger problem with this approach that is: it will fail for domains that aren't directly beneath the TLD. This is domains in Australia, UK, Japan, and many other countries, who have hierarchies: .co.jp, .co.uk, .com.au, and so on.

Whether or not that is of any concern to the OP, I don't know but it's something to be aware of if you're after a "fix all" answer.

The OP hasn't yet made it clear whether he wants a generic solution or a solution for a single (or small group) of known domains. If it's the latter, see my other note about using Zigdon's approach. If it's the former, then proceed with Vinko's approach taking into account the information in this post.

Edit: One thing I've left out until now, which may or may not be an option for you business-wise, is to go the other way. All our sites redirect http://www.domain.com to http://domain.com. The folks at http://no-www.org make a pretty good case (IMHO) for this being the "right" way to do it, but it's still certainly just a matter of preference. One thing is for sure though, it's far easier to write a generic rule for that kind of redirection than this one.

離殇 2024-07-11 03:27:13

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

^example\.com$

而不是他的建议:

^example\.com(.*)

否则,您将不仅仅匹配 example.com,您'将匹配 example.comcast.net、example.com.au 等。

Zigdon has the right idea except his regex isn't quite right. Use

^example\.com$

instead of his suggestion of:

^example\.com(.*)

Otherwise you won't just be matching example.com, you'll be matching things like example.comcast.net, example.com.au, etc.

罪歌 2024-07-11 03:27:13

@org 0100h 是的,问题的描述中遗漏了许多变量,您的所有观点都是有效的,应该在实际实施时解决。 您提出的正则表达式既有优点也有缺点。 一方面,它更容易且面向未来,另一方面,如果在 Host 标头中发送,您真的想匹配 example.foobar 吗? 当您最终重定向到错误的域时,可能会出现一些边缘情况。 第三种替代方法是修改正则表达式以使用实际域的列表,如果不止一个,例如

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

(请注意 chris,那个更改%1)

@chrisofspades 这并不意味着要替换它,你的第二个条件确保它没有 www,而我的没有。 它不会更改 %1、%2、%3 的值,因为它不存储匹配项(哦,它不使用括号)。

@org 0100h Yes, there are many variables left out of the description of the problem, and all your points are valid ones and should be addressed in the event of an actual implementation. There are both pros and cons to your proposed regex. On the one hand it's easier and future proof, on the other, do you really want to match example.foobar if sent in the Host header? There might be some edge cases when you'll end up redirecting to the wrong domain. A thrid alternative is modifying the regex to use a list of the actual domains, if more than one, like

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

(Note to chris, that one will change %1)

@chrisofspades It's not meant to replace it, your condition number two ensures that it doesn't have www, whereas mine doesn't. It won't change the values of %1, %2, %3 because it doesn't store the matches (iow, it doesn't use parentheses).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文