在多域设置中,我使用具有以下条件的巨大的.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>
还是有更好的方法来解决这个问题?
答案 0 :(得分:1)
我们无法更改服务器设置,因此维护重写规则的唯一方法是htaccess。
您无法在.htaccess
中执行此操作,因为您无法在Include
文件中使用.htaccess
指令。没有其他方法可以包含配置文件。而且,有条件地包括此条件的唯一方法是使用<If>
块。
您可能会将所有指令都放在<If>
块中,而不是使用[S=1000]
标志。但是,这并非没有严重的警告。在<If>
表达式被尽早处理的同时,<If>
块的内容在请求中被 late (“ last”)合并。实际上,在请求已映射到文件系统之后,它似乎合并得很晚。这意味着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>
,而在每个vHost中只需使用<VirtualHost>
必要的文件,而不是使用Include
块。没有警告。
.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
。