18

我正在开发一个虚拟域系统。我将通配符 DNS 设置为*.loc,并且正在尝试处理我的.htaccess文件。以下代码有效:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www.)?example\.loc$ [NC]
RewriteCond %{REQUEST_URI} !^/example/
RewriteRule (.*) /example/$1 [L,QSA]

但是,我希望它可以与我输入的任何内容一起使用。但是,我需要%{REQUEST_URI}针对作为域找到的文本进行检查。我尝试使用此代码:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www.)?([a-zA-Z0-9-]*.)?([a-zA-Z0-9-]+)\.loc$ [NC]
RewriteCond %{REQUEST_URI} !^/%3/
RewriteRule (.*) /%3/$1 [L,QSA]

但是该行RewriteCond %{REQUEST_URI} !^/%3/导致我的代码引发内部服务器错误。我知道这是因为我的代码中有 %N,但是有没有办法可以使用它?我需要这一行,否则我的代码会因内部重定向而失败。

我希望这对某人有意义。我所需要的只是能够在后面的 RewriteCond 中反向引用 RewriteCond。

4

1 回答 1

47

您在这里做错了两件事。

首先,你的%{HTTP_HOST}正则表达式不好。您需要转义这些.点,否则它们将被视为“任何不是换行符的字符”。这实质上使%3反向引用成为 TLD 之前主机名的最后一个字符(例如http://blah.bar.loc% 3 = r)。

其次,您不能在 a 的正则表达式中使用反向引用RewriteCond,只能在左侧字符串中使用,这是一种奇怪的限制。但是,您可以\1在正则表达式中使用引用,以便您可以构造一个聪明的左侧字符串来匹配。像这样的东西%3::%{REQUEST_URI},然后你可以像这样匹配:!^(.*?)::/\1/?. 这个正则表达式本质上说:“匹配并分组 :: 之前的第一个文本块然后确保:: 之后的文本块”开头。/(first block)

所以你的规则应该是这样的:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?([a-zA-Z0-9-]*\.)?([a-zA-Z0-9-]+)\.loc$ [NC]
RewriteCond %3::%{REQUEST_URI} !^(.*?)::/\1/?
RewriteRule (.*) /%3/$1 [L,QSA]
于 2013-04-12T21:21:57.160 回答