Apache HTTP Server 版本 2.4

本文档是对 mod_rewrite 参考文档 的补充。它描述了如何使用 mod_rewrite 创建动态配置的虚拟主机。
我们希望为我们域中解析的每个主机名自动创建一个虚拟主机,而无需创建新的 VirtualHost 部分。
在本示例中,我们假设我们将使用主机名 www.SITE.example.com 为每个用户提供服务,并将他们的内容存储在 /home/SITE/www 中。
RewriteEngine on
RewriteMap    lowercase int:tolower
RewriteCond   "${lowercase:%{HTTP_HOST}}"   "^www\.([^.]+)\.example\.com$"
RewriteRule   "^(.*)" "/home/%1/www$1"
内部 tolower RewriteMap 指令用于确保使用的主机名全部为小写,以避免在必须创建的目录结构中出现歧义。
在 RewriteCond 中使用的括号将捕获到反向引用 %1、%2 等中,而在 RewriteRule 中使用的括号将捕获到反向引用 $1、$2 等中。
与本文档中讨论的许多技术一样,mod_rewrite 并不是完成此任务的最佳方法。相反,您应该考虑使用 mod_vhost_alias,因为它可以更优雅地处理除提供静态文件之外的任何内容,例如任何动态内容和别名解析。
mod_rewrite 实现动态虚拟主机来自 httpd.conf 的此摘录与 第一个示例 做相同的事情。前半部分与上面的对应部分非常相似,只是有一些更改,这些更改是为了向后兼容以及使 mod_rewrite 部分正常工作而必需的;后半部分配置 mod_rewrite 来完成实际工作。
由于 mod_rewrite 在其他 URI 转换模块(例如 mod_alias)之前运行,因此必须告诉 mod_rewrite 明确忽略任何将由这些模块处理的 URL。并且,由于这些规则否则将绕过任何 ScriptAlias 指令,因此我们必须让 mod_rewrite 明确执行这些映射。
# get the server name from the Host: header
UseCanonicalName Off
# splittable logs
LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon
CustomLog "logs/access_log" vcommon
<Directory "/www/hosts">
    # ExecCGI is needed here because we can't force
    # CGI execution in the way that ScriptAlias does
    Options FollowSymLinks ExecCGI
</Directory>
RewriteEngine On
# a ServerName derived from a Host: header may be any case at all
RewriteMap  lowercase  int:tolower
## deal with normal documents first:
# allow Alias "/icons/" to work - repeat for other aliases
RewriteCond  "%{REQUEST_URI}"  "!^/icons/"
# allow CGIs to work
RewriteCond  "%{REQUEST_URI}"  "!^/cgi-bin/"
# do the magic
RewriteRule  "^/(.*)$"  "/www/hosts/${lowercase:%{SERVER_NAME}}/docs/$1"
## and now deal with CGIs - we have to force a handler
RewriteCond  "%{REQUEST_URI}"  "^/cgi-bin/"
RewriteRule  "^/(.*)$"  "/www/hosts/${lowercase:%{SERVER_NAME}}/cgi-bin/$1"  [H=cgi-script]
此安排使用更高级的 mod_rewrite 功能从单独的配置文件中找出从虚拟主机到文档根目录的转换。这提供了更大的灵活性,但需要更复杂的配置。
vhost.map 文件应如下所示
customer-1.example.com /www/customers/1
customer-2.example.com /www/customers/2
# ...
customer-N.example.com /www/customers/N
httpd.conf 应包含以下内容
RewriteEngine on
RewriteMap   lowercase  int:tolower
# define the map file
RewriteMap   vhost      "txt:/www/conf/vhost.map"
# deal with aliases as above
RewriteCond  "%{REQUEST_URI}"               "!^/icons/"
RewriteCond  "%{REQUEST_URI}"               "!^/cgi-bin/"
RewriteCond  "${lowercase:%{SERVER_NAME}}"  "^(.+)$"
# this does the file-based remap
RewriteCond  "${vhost:%1}"                  "^(/.*)$"
RewriteRule  "^/(.*)$"                      "%1/docs/$1"
RewriteCond  "%{REQUEST_URI}"               "^/cgi-bin/"
RewriteCond  "${lowercase:%{SERVER_NAME}}"  "^(.+)$"
RewriteCond  "${vhost:%1}"                  "^(/.*)$"
RewriteRule  "^/cgi-bin/(.*)$"                      "%1/cgi-bin/$1" [H=cgi-script]