mod_rewrite忽略子目录中的规则

时间:2011-06-22 21:22:58

标签: apache .htaccess mod-rewrite subdomain

想要重写行为(内部重写!)

http://<subdomain>.domain.tld/<path> -> /<subdomain>/<path>
http://www.domain.tld/path/file.php  -> /www/path/file.php
http://project.domain-tld/index.php  -> /project/index.php

文件夹结构:

/                        root
    .htaccess
    /www                 www.domain.tld
        index.php
        /www
            file.php
        /foo
            /bar
                file.php
    /project             project.domain.tld
        index.php
        someRandomFiles
    /somesubdomain       somesubdomain.domain.tld
        index.php
        someRandomFiles
    /anothersubdomain    anothersubdomain.domain.tld
         index.php
         someRandomFiles

完整.htaccess

# Unicode
AddDefaultCharset utf-8

# Activate mod_rewrite
RewriteEngine on
RewriteBase /

# Subdomains
#  Extract (required) subdomain (%1), and first path element (%3), discard port number if present (%2)
RewriteCond %{HTTP_HOST}<>%{REQUEST_URI} ^([^.]+)\.janbuschtoens\.de(:80)?<>/([^/]*) [NC]
#  Rewrite only when subdomain not equal to first path element (prevents mod_rewrite recursion)
RewriteCond %1<>%3 !^(.*)<>\1$ [NC]
#  Rewrite to /subdomain/path
RewriteRule ^(.*) /%1/$1 [L]

我的.htaccess似乎有效。你可以在这里进行测试:

但子目录中存在一些奇怪的行为。如果请求路径中的第一个目录与子域本身具有相同的名称,mod_rewrite似乎会忽略该规则。例如:

  • http://www.domain.tld/foo/bar/file.php -> /www/foo/bar/file.php - Fine!
  • http://www.domain.tld/ -> /www/ - Fine!
  • http://www.domain.tld/www/ -> /www/ - Should be: /www/www/
  • http://www.domain.tld/www/www/ -> /www/www/ - Should be: /www/www/www/

进行另一次现场测试:

似乎规则被忽略了。

1 个答案:

答案 0 :(得分:1)

这是我能够提出的唯一好规则,否则在初始重写之后(这很容易)它进入循环(这就是问题)。例如:www.domain.com/www/123.png被正确地重定向到/www/www/123.png,但后来进入下一个循环,在那里它被重定向到/www/www/www/123.png然后一次又一次。

如果FINAL文件名已存在,则会调用此规则

RewriteCond %{HTTP_HOST} ^(.+)\.domain\.com$
RewriteCond %{DOCUMENT_ROOT}/%1/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/%1/$1 -d
RewriteRule ^(.*)$ /%1/$1 [QSA,L]

例如:如果您请求www.domain.com/www/123.png,并且文件/文件夹WEBSITEROOT/www/www/123.png存在,那么它将被重写,否则没有。

此处相同:如果您请求meow.domain.com/ ..但驱动器上没有WEBSITEROOT/meow/文件夹,则无处可去。

请注意,如果您有与子域名同名的子文件夹,这仍然无济于事。例如:如果您请求www.domain.com,则应将其重写为WEBSITEROOT/www/ ...但如果您还有WEBSITEROOT/www/www/,那么(因为循环)它将被重写为WEBSITEROOT/www/www/代替。

不幸的是,我还没有找到绕过它的方法。如果您愿意 - 您可以尝试将您的规则与我的相结合。