httpd.conf Priority Against .htaccess

在httpd.conf里可以用allowoverride设置让.htaccess生效或失效,这让我想当然地认为httpd.conf比.htaccess有更高的优先级,最后发现并不是这样。 今天我调整了我管辖的几十个域名的A record, CName, MX。为了让域名规划更加整齐,也方便以后的更改,我把同组域名(启用ghs.google.com的多个alias)都用mod_rewrite做了301 redirect,指向了primary domain。因为Rewrite必须写在Directory directive里,所以我在httpd.conf里写完Virtualhost directives之后,专门开篇Directory,把各组域名的子域名重写规则都放在一起,方便阅读和理解。 域名启用了wildcard子域名,我想让一些特殊的子域名在wildcard子域名定向前先行重定向,所以我把这些特殊子域名的重定向写在了httpd.conf里面。我管辖的域名都按同一个规则设置特殊子域名,我也不想打开一个个.htaccess一一编辑,把这些规则写在httpd.conf是最理想的。 我原以为httpd.conf优先级高于.htaccess,所以当特殊子域名在httpd.conf读到匹配的规则,即行重定向,而不再当作wildcard子域名处理。但是我错了。关于优先级的完整理解应该是: httpd.conf可以设置让.htaccess生效 (allowoverride all) 或生效 (allowoverride non) ,这没有错。 但一旦httpd.conf让.httaccess生效,.htaccess里的设置就优于httpd.conf。对啊,allowoverride就是这个意思,我怎么就这么傻呢。 如果不是magento之类的程序,即使特殊子域名被当成wildcard子域名,在.htaccess里匹配不到规则,特殊子域名还是有机会在httpd.conf里完成我期待中的重定向。magento (说到底是zend frameword) 带来一种规则——所有不匹配的规则统统重定向到index.php,这让我在httpd.conf里的规则再也没有机会捕捉到特殊子域名 (全被当成wildcard子域名被.htaccess捕获了)。 思前想后,我只好想出一招:把特殊子域名作为ServerName或ServerAlias编成专门的VirtualHost directive,位置必须放在wildcard子域名所在的VirtualHost directive之前,然后为特殊子域名和wildcard子域名设置不同的DocumentRoot。因为RewriteCond和RewriteRule都是基于Directory directive的,既然分开在不同的directory,wildcard子域名的.htaccess就没有机会override特殊子域名了。

Published
Categorized as 杂草