【问题标题】:mod_rewrite regex (too many redirects)mod_rewrite 正则表达式(重定向太多)
【发布时间】:2011-05-03 11:08:08
【问题描述】:

我正在使用mod_rewrite,将子域转换为目录 url。 (解决方案from here)。当我明确地为一个子域编写规则时,它可以完美运行:

RewriteCond %{HTTP_HOST}   ^[www\.]*sub-domain-name.domain-name.com [NC]
RewriteCond %{REQUEST_URI} !^/sub-domain-directory/.*
RewriteRule   ^(.*)  /sub-domain-directory/$1  [L]

但是,如果我尝试匹配所有子域,则会导致 500 内部错误(日志显示重定向过多)。代码是:

RewriteCond %{HTTP_HOST}   ^[www\.]*([a-z0-9-]+).domain-name.com [NC]
RewriteCond %{REQUEST_URI} !^/%1/.*
RewriteRule   ^(.*)  /%1/$1  [L]

谁能提出问题出在哪里以及如何解决?

【问题讨论】:

  • 您正在将每个页面重定向到自身,但我不知道如何解决。
  • @Andrew 不,不是因为 OP 想要使用 mod_rewrite。尝试在您的正则表达式捕获组中放置一个静态子域,看看是否可行。
  • @Michael:我猜你的意思就像我在问题中写的那样。静态子域有效。它的行为与蒂姆·斯通和时间机器所指出的完全一样。我还没有尝试 Tim 的解决方案。
  • 类似的东西,但尝试在第二个示例中将([a-z0-9]+) 替换为(sub-domain-name),看看是否可行。

标签: .htaccess mod-rewrite subdomain wildcard-subdomain


【解决方案1】:

你的第二个 RewriteCond 永远不会返回 false,因为你不能在你的测试子句中使用反向引用(它们是在解析过程中编译的,因为不会发生变量扩展,所以这是不可能的)。您实际上是在测试以文字文本 /%1/ 开头的路径,这不是您想要的。鉴于您在每个目录的上下文中操作,规则集最终将再次被应用,从而导致如下所示的转换:

路径 -> 子/路径 子/路径 -> 子/子/路径 子/子/路径 -> 子/子/子/路径 ...

在服务器不正常并引发 500 错误之前,这会持续大约十次迭代。有几种不同的方法可以解决此问题,但我将选择一种与您尝试采用的方法最相似的方法。我还要修改第一个 RewriteCond,因为正则表达式有点缺陷:

RewriteCond %{HTTP_HOST}       ^([^.]+)\.example\.com$ [NC]
RewriteCond %1                !=www
RewriteCond %1#%{REQUEST_URI} !^([^#]+)#/\1/
RewriteRule .* /%1/$0 [L]

首先,它检查 HTTP_HOST 值并捕获子域,无论它可能是什么。然后,假设您不希望这种转换发生在 www 的情况下,它会确保捕获不匹配。之后,它使用正则表达式自己的内部反向引用来查看 REQUEST_URI 是否以子域值开头。如果没有,它会将子域作为目录添加到前面,就像现在一样。

这种方法的潜在问题是,如果您访问的路径以与请求发送到的子域相同的名称开头,例如 sub.example.com/sub/时间>。另一种方法是检查 REDIRECT_STATUS 环境变量以查看是否已经执行了内部重定向(即,这个前置步骤已经发生):

RewriteCond %{HTTP_HOST}           ^([^.]+)\.example\.com$ [NC]
RewriteCond %1                     !=www
RewriteCond %{ENV:REDIRECT_STATUS}  =""
RewriteRule .* /%1/$0 [L]

【讨论】:

  • 嘿蒂姆,它的行为就像你指出的那样,它确实在 10 次递归后停止。我将尝试了解您的 cmets 并尝试解决方案。谢谢!
  • 这行得通。谢谢 :)。这 4 行可用于在单个服务器上设置多个站点、多个子域,甚至无需 VirtualDocumentRoot。 mod_rewrite 确实很强大。
  • @JP19:很高兴听到它在工作,没问题;很高兴能帮助你! :) 是的,mod_rewrite 是一个非常有用的工具。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-14
  • 2015-06-06
  • 2015-01-04
  • 1970-01-01
  • 2013-07-25
  • 2018-04-19
  • 1970-01-01
相关资源
最近更新 更多