我可以在Apache 2.4的.htaccess中使用嵌套的<If>指令吗?

我正在尝试使用我的.htaccess文件中的Redirect和RedirectMatch规则来模拟我的站点以前版本的永久链接结构。

我有不同的规则,我会适用于从我的旧网站不同的path。 有些目录没有模拟,我希望他们redirect到一个单一的位置。 有些目录在不同位置包含许多项目(数千个),我希望它们能够巧妙地redirect到新站点中正确的新位置。

似乎我可以在<If>上通过基本的正则expression式testing来防范和分组相关项目,以防止所有包含的分组redirect被testing,如果它们永远不匹配的话。 在这种方法中,生成的configuration看起来是合乎逻辑和一致的,并且可以很容易地自动生成:

<If "%{REQUEST_URI} =~ m#^/categories/software/.*#"> # These rules aren't considered if the request wasn't for a subpath of categories/software. <If "%{REQUEST_URI} =~ m#^/categories/software/store/.*#"> # All old store pages now invalid, go to main store. RedirectMatch 301 .* /software-store/ </If> # Regexes for each category of software to group them logically. # And so that 1,000s of redirects don't get considered on each page load. <If "%{REQUEST_URI} =~ m#^/categories/software/item/.*#"> # Loads and loads of redirect lines for pages with arbitrary rules to product pages. Redirect 301 "/categories/software/item/foo" /software-store/games/foo Redirect 301 "/categories/software/item/bar" /software-store/productivity/bar Redirect 301 "/categories/software/item/baz" /software-store/misc/baz # ... </If> <If "%{REQUEST_URI} =~ m#^/categories/software/dlc/.*#"> # Loads and loads of redirect lines. It could also be grouped into subdirectories of dlc/ and so on. # ... </If> </If> # ... 

对于一个巨大的目录,一些守护正则expression式可以阻止数千次无用的testing。

我正在使用Apache 2.4,其中<If>指令是可用的,但上述指令没有我期望的效果。 内部的<If>完全被忽略。

如果我删除了封闭的<If>,并且只有最内层的<If>出现了规则,所以我不相信我的语法或我的redirect规则是错误的。

我怀疑问题是我不能嵌套<If>,虽然这似乎是一个非常普遍的事情要做。 在文档中,我看不到有关嵌套的任何提及,允许或以其他方式。 http://httpd.apache.org/docs/2.4/mod/core.html#if

我可以嵌套<If>指令吗? 如果是这样/如果不是这样的话,你能指出我为什么说文档的部分。

一个<If>指令不能嵌套在另一个<If>指令中,但可以嵌套在其他部分如<Directory><Location><Files><IfModule>

If 2.4指令的Apache 2.4文档有以下注意事项:

不是一种脚本语言

这个指令的名字对于程序员和pipe理员来说是非常熟悉的,但是不应该和脚本语言中的对象混淆。 例如,当前的实现不考虑在另一个内部有一个<If>部分的可能性(内部的<If>将被忽略)。

没有理由为什么他们select不允许嵌套的<If>指令。

关于在文档中提供的嵌套的唯一其他信息表明每个节types是否可以嵌套是不同的:

嵌套的部分

某些节types可以嵌套在其他节types中。 一方面, <Files>可以在<Directory> 。 另一方面, <If>可以用在<Directory><Location><Files>部分(但不在另一个<If> )。 命名部分的正则expression式行为相同。

Apache并不一定按顺序“读取”configuration,而是经历一个非常复杂的合并过程。 正因为如此,最好的“匹配”有时难以预测,几乎总是需要考虑在各个configuration部分出现的指令。

您可以查看configuration部分的文档 ,特别注意合并部分以更好地理解这一点。

另请注意,您可能会得到更好的结果,例如<Else>和<ElseIf> 。