有条件地包括Apache配置
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有条件地包括Apache配置相关的知识,希望对你有一定的参考价值。
在多域设置中,我使用具有以下条件的巨大.htaccess文件来跳过大量重写规则,具体取决于所请求URL的HTTP_HOST。
RewriteCond %{HTTP_HOST} !^www.example.com$
## skip next 1000 rules, if we`re not on the .com domain.
RewriteRule .? - [S=1000]
RewriteRule ^foo https://www.example.com/bar [R=301,L]
...
RewriteCond %{HTTP_HOST} !^www.example.co.uk$
## skip next 500 rules, if we`re not on the .co.uk domain.
RewriteRule .? - [S=500]
RewriteRule ^foo https://www.example.co.uk/bar [R=301,L]
...
由于我有几个域总共有大约4000个重写规则,我宁愿将配置拆分成几个文件并根据当前的HTTP_HOST加载这些文件。
是否可以在表达式中使用include指令而不是
"RewriteRule .? - [S=500]"
?
这样的事情可能是:
<If "%{HTTP_HOST} =~ ^www.example.com$">
Include conf/com.rewriterules.conf
</If>
还是有更好的方法来解决这个问题?
我们无法更改服务器设置,因此维护重写规则的唯一方法是htaccess。
你不能在.htaccess
中这样做,因为你不能在Include
文件中使用.htaccess
指令。没有其他方法可以包含配置文件。并且有条件地包括这个的唯一方法是使用<If>
块。
您可能拥有<If>
块内的所有指令,而不是使用[S=1000]
标志。然而,这并非没有严重的警告。虽然<If>
表达式是早期处理的,但<If>
块的内容在请求中合并得晚(“最后”)。实际上,在请求已映射到文件系统之后,它似乎很晚才合并。这意味着RewriteRule
指令与已解析的文件系统路径匹配,而不是请求的URL路径!因此,这需要在任何RewriteRule
指令中进行说明 - 或者更改为使用mod_alias Redirect
或RedirectMatch
作为外部重定向,这些重定向始终作用于请求的URL。
您可以在服务器配置中执行此操作(在Include
块中使用<If>
指令)。但同样的警告如上所述 - <If>
区块合并得很晚。
但请注意,您的语法不太正确。如果你想匹配一个正则表达式,那么你就会遗漏正则表达式周围的斜线分隔符。它应该是:
<If "%{HTTP_HOST} =~ /^www.example.com$/">
Include conf/com.rewriterules.conf
</If>
或者使用更简单的字符串/相等比较:
<If "%{HTTP_HOST} == 'www.example.com'">
:
然而,不是使用<If>
块,最好为每个域都有一个单独的<VirtualHost>
,在每个vHost中你可以简单地Include
必要的文件。没有警告。
暂时没有,但是...如果你所有的“重写规则”都是外部重定向(如你的例子中),否则会导致404(即它们不存在)的请求,那么你不应该这样做所有这些重定向都在Apache配置中开始(.htaccess
或服务器配置)。
它们应该在您的应用程序逻辑中,并且只在您的应用程序确定它将导致404时才“迟到”处理。这优先考虑正常的站点流量,而不是优先重定向。通过Apache配置中的重定向,可以在每个请求中处理它们 - 这通常是不必要的。
RewriteRule ^foo https://www.example.com/bar [R=301,L] : RewriteRule ^foo https://www.example.co.uk/bar [R=301,L]
也许只是您的示例代码,但您不需要在RewriteRule
替换外部重定向中指定绝对URL。它可能是根相对的:/bar
。
以上是关于有条件地包括Apache配置的主要内容,如果未能解决你的问题,请参考以下文章