标题基本概括了所有内容。:-) 我有很多虚拟主机,我想在 httpd.conf 文件的顶部放置一个重写块,无论请求可能被定向到哪个虚拟主机,它都会重写 URL。我该怎么做?
我发现了这一点,但我的问题是一样的:如何在不使用 .htaccess 文件并为每个虚拟主机执行其他操作的情况下做到这一点?
天哪!
标题基本概括了所有内容。:-) 我有很多虚拟主机,我想在 httpd.conf 文件的顶部放置一个重写块,无论请求可能被定向到哪个虚拟主机,它都会重写 URL。我该怎么做?
我发现了这一点,但我的问题是一样的:如何在不使用 .htaccess 文件并为每个虚拟主机执行其他操作的情况下做到这一点?
天哪!
RewriteOptions InheritDown
在父范围(例如 httpd.conf)中指定以在不修改子虚拟主机的情况下应用您的规则。
这仅适用于RewriteEngine
指令设置为的虚拟主机on
:
请注意,虚拟主机不会继承重写配置。这意味着您需要为希望在其中使用重写规则的每个虚拟主机设置一个 RewriteEngine on 指令。
(来源)
Apache 从 2.4.8 开始支持这一点(在原始问题出现时不可用)。
来自文档RewriteOptions
:
继承下来
如果启用此选项,所有子配置将继承当前配置的配置。相当于在所有子配置中指定 RewriteOptions Inherit。有关如何处理父子关系的更多详细信息,请参阅继承选项。在 Apache HTTP Server 2.4.8 及更高版本中可用。
继承之前
与上面的 InheritDown 类似,但当前范围的规则在任何子范围中指定的规则之前应用。在 Apache HTTP Server 2.4.8 及更高版本中可用。
忽略继承
此选项强制当前和子配置忽略将从指定 InheritDown 或 InheritDownBefore 的父级继承的所有规则。在 Apache HTTP Server 2.4.8 及更高版本中可用。
(http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriteoptions)
默认情况下,来自主服务器上下文的 mod_rewrite 配置设置不会被虚拟主机继承。要将主服务器设置应用于虚拟主机,您必须在每个<VirtualHost>
部分中放置以下指令:
RewriteEngine On
RewriteOptions Inherit
单击http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html查找更多信息
看起来最简单的解决方案是添加
RewriteOptions inherit
到每个 VirtualHost 指令。这至少比处理 .htaccess 文件要简单得多。Apache 非常清楚这一事实
默认情况下,不会继承重写配置。这意味着您需要为您希望在其中使用它的每个虚拟主机设置一个 RewriteEngine on 指令。(http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html)
显然,更改默认值的方法是通过子项(虚拟主机或导演)中的 RewriteOptions,因此您必须在每个子项中执行一些操作。
我从来没有测试过它,所以它可能不起作用,但我会尝试include
在所有虚拟主机块中添加一个指令到一个文件中。您必须更改每个虚拟主机配置块一次,但在那之后,您应该有一个可以进行更改的中心位置。YMMV。
如果您只是想改写名称的域部分中的某些内容,例如修复常见的拼写错误,您甚至不需要'inherit' 选项。我设置了一个无名虚拟主机来捕获所有无效的主机名并在重定向它们之前正确地重新拼写它们。
由于这使用重定向,因此将在应用重写后找到适当的虚拟主机。
Options +Indexes +FollowSymLinks
RewriteEngine on
# If it begins with only domain.com, prepend www and send to www.domain.com
RewriteCond %{HTTP_HOST} ^domain [NC]
RewriteRule ^(.*) http://www.domain.com$1 [L,R=301]
# Correct misspelling in the domain name, applies to any VirtualHost in the domain
# Requires a subdomain, i.e. (serviceXXX.)domain.com, or the prepended www. from above
RewriteCond %{HTTP_HOST} ^([^.]+\.)dommmmmain\.com\.?(:[0-9]*)?$ [NC]
RewriteRule ^(.*) %{HTTP_HOST}$1 [C]
RewriteRule ^([^.]+\.)?domain.com(.*) http://$1domain.com$2 [L,R=301]
# No-name virtual host to catch all invalid hostnames and mod_rewrite and redirect them
<VirtualHost *>
RewriteEngine on
RewriteOptions inherit
</VirtualHost>
您可能希望使用 InheritDownBefore 以避免向您的虚拟主机添加更多垃圾。
全局 letencrypt 别名的示例:
# letsencrypt
<IfModule alias_module>
Alias /.well-known/ /var/www/html/.well-known/
</IfModule>
<IfModule mod_rewrite.c>
# prevent vhost rewrites from killing the alias
RewriteEngine On
RewriteOptions InheritDownBefore
RewriteCond %{REQUEST_URI} ^/\.well\-known
RewriteRule . - [L,PT]
</IfModule>
然后您可以在每个虚拟主机中执行此操作,无需其他指令:
<VirtualHost *:80>
....
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^/.* /index.php [L,PT]
</IfModule>
</VirtualHost>
谢谢楼上大家的回答。它帮助我找到了答案。
问题已经得到解答,我只是想添加一个示例,以防您使用 Google Compute Engine。它说它需要Apache HTTP Server 2.4.8
但它适用于Apache/2.4.25 (Debian)
. 即使我尝试升级,我也无法过去Apache/2.4.25
。它说这个版本是最新版本。
这是一个如何实现的示例。
RewriteOptions InheritDown
RewriteCond %{HTTP_HOST} ^www\. [NC,OR]
RewriteCond %{HTTP_HOST} !\.co$ [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)\.[^.]+$ [NC]
RewriteRule ^ https://%1.co%{REQUEST_URI} [L,NE,R=301]
<VirtualHost *:80>
RewriteEngine On
ServerAlias *.*
</VirtualHost>
另请注意(用于测试):
当你测试你的重写引擎时。由于缓存和cookies,很容易混淆它是否工作。如果你让它在浏览器上工作一次,即使你删除了重写代码,它也会继续工作。测试重写有时真的很烦人。您可能认为它有效,但随后它停止或启动。
测试重写代码的最佳方法是在浏览器中打开一个隐身选项卡,清除或 cookie 和缓存。打开开发者模式以防万一。不要只是刷新。您需要单击 URL 并刷新。或打开新标签。或将 URL 复制/粘贴到新窗口中。如果您使用相同的窗口进行刷新,它可能只是重做过去的结果,而不是更新新代码。
我一直将“包罗万象”的 VHost 用于我想要全面的指令,比如......
Listen 80
NameVirtualHost *:80
<VirtualHost *:80>
ErrorLog "/var/log/apache2/error_log"
</VirtualHost>
<VirtualHost *:80>
ServerName alloftherestoftheVHosts.com
DocumentRoot "/ServiceData/.........
............
而且它似乎总是 有效......错误日志被正确组合,等等......但这可能是早期/冲突/志同道合的指令的结果。
个人笔记.. 想出 Apache 配置模式和语法的人是一个 dingbat,或者是一群 dingbat,他们在洞穴中花费了太多时间......整个事情应该被驱除和 XML 化,或者什么! 尽管它们都有很大的不同...... Cherokee的 Hello-Kitty 设置过程......到恶毒简洁的NGinx配置......两者都更加合乎逻辑......