正则表达无限循环

时间:2016-01-11 20:12:02

标签: regex apache .htaccess mod-rewrite

我有这个服务器,其中指向了两个域名。所以在我的.htaccess文件中,我想制定一个简单的规则来说明这一点:

如果你来自test.domain.com然后转到文件夹X,如果你来自the-other-sub.domain.com然后转到文件夹Y.这意味着我移动了其中一个子域名,所以我想这样做,以便重定向到正确的网址(以防人们关注深层链接。例如,如果有人转到http://test.domain.com/path/to/a/page,他们会被重定向到/path/to/a/page新文件夹。

但是,我努力这样做。我不能得到的是,为什么这个代码:

Options +FollowSymLinks
RewriteEngine on

RewriteBase /
RewriteCond %{HTTP_HOST} ^subdomain.domain.com$ 
RewriteRule ^(.*)$ /test/$1 [L,R=301]

离开我,所以如果我转到subdomain.domain.com/abc,则浏览器会将我发送给subdomain.domain.com/test/test/test/test/test/test/test/test/test/test/test/abc 然后抱怨我有无尽的循环。请不要使用Apache的mod_rewrite.c文档的智能链接......我已经阅读过了,这就是它带给我的地方。我知道*表示匹配0次或更多次,但我不知道为什么会一遍又一遍地复制目标字符串......? /test/不是正则表达式中的变量,是吗?那为什么重复呢?

2 个答案:

答案 0 :(得分:2)

如果您无条件地重定向到/test/...,那么它会在重定向的网址之前继续添加/test/

要修复使用此规则:

Options +FollowSymLinks
RewriteEngine on

RewriteBase /
RewriteCond %{HTTP_HOST} ^subdomain\.domain\.com$ [NC]
RewriteRule ^((?!test/).*)$ /test/$1 [L,R=301,NC]

(?!test/)是否定前瞻性条件,这意味着只有在/test/开始时才添加/test/

答案 1 :(得分:0)

@ anubhava的答案是一个很好的解决方案。

在您当前的版本(以及@ anubhava')中,[L,R = 301]标志会导致重定向应用,以便再次提交新生成的URL。这就是为什么你必须注意不要重新应用这种重定向。

然而,如果您不确实需要来生成HTTP 301响应状态代码,那么有一种更简单的方法。 然后从您的原始版本中,您可以简单地:

  • 删除最初的" /"在替换表达中
  • 放弃" R = 301"标志

所以你的版本变成了:

Options +FollowSymLinks
RewriteEngine on

RewriteBase /
RewriteCond %{HTTP_HOST} ^subdomain.domain.com$ 
RewriteRule ^(.*)$ test/$1 [L]

这样,重定向只会发生一次:第二次,Apache会识别出网址没有改变,然后停止循环。