• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 动态虚拟主机与 mod_rewrite

    本文档是mod_rewrite参考文档的补充。它描述了如何mod_rewrite用于创建动态配置的虚拟主机。

    mod_rewrite不是配置虚拟主机的最佳方法。在采用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"
    
    讨论区
    您将需要注意DNS解析-Apache不处理名称解析。您需要为每个主机名创建CNAME记录,或DNS通配符记录。创建DNS记录超出了本文档的范围。

    内部的tolowerRewriteMap指令用于确保所使用的主机名全部为小写字母,以便在目录结构中不存在必须创建的歧义。

    在使用括号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]