Apache mod_rewrite中的REQUEST_URI使用实例
如下规则:
RewriteEngineon #sitemapindexxmlrewrite RewriteRule^sitemap_([a-zA-Z0-9_\-]+)\.xml$/sitemap/$1 #redirectedallinvalidrequestthetheindexbootstrap RewriteRule!\.(htm|txt|xml|css|js|swf|gif|jpg|png|ico)$index.php[L]
假设访问sitemap_index.xml,当经过两次RewriteRule之后,传给bootstrap程序index.php的$_SERVER['REQUEST_URI']值仍然是/sitemap_index.xml,但实际上希望是/sitemap/index,这样index.php才能正确的进行urlroute。
要达到这个目的,有两个方法。
第一种方式,配合mod_proxy,将第一条重写规则改为
#sitemapindexxmlrewrite RewriteRule^sitemap_([a-zA-Z0-9_\-]+)\.xml$/sitemap/$1[P,L]
这样将在内部产生一个新的URL请求,REQUEST_URI的值也就变成了新的/sitemap/index。但这种方法制造了额外的一次http请求。
第二种方法,将第一条规则改为
#sitemapindexxmlrewrite RewriteRule^sitemap_([a-zA-Z0-9_\-]+)\.xml$/sitemap/$1[E=REQUEST_URI:/sitemap/$1]
或者
#sitemapindexxmlrewrite RewriteRule^sitemap_([a-zA-Z0-9_\-]+)\.xml$index.php[E=REQUEST_URI:/sitemap/$1,L]
然后通过$_SERVER['REDIRECT_REQUEST_URI']变量得到值/sitemap/index(注意使用E设置环境变量的时候,mod_rewrite自动给变量加上REDIRECT_前缀)。
有趣的是在Rewrite的过程中REQUEST_URI的值始终保持是原始的请求URI,但在mod_setenvif中提供的SetEnvIf/SetEnvIfNoCase中所使用的Request_URI属性得到的却是经过rewrite之后的地址而非原始GET/POST中的URI。
所以如果在httpd.conf/httpd-vhosts.conf中想使用
SetEnvIfNoCaseRequest_URI"sitemap"...
来针对sitemap设置环境变量的话是不起作用的,因为这时候传给SetEnvIfNoCase进行判断的Request_URI是index.php而不是sitemap_index.xml或sitemap/index。想要得到原始的Request_URI信息就必须在rewrite规则的最开始进行保存,比如在rewrite规则开头加入
SetEnvIfNoCaseRequest_URI"(^/sitemap_.*\.xml)"MY_REQUEST_URI_BF_REWRITE=$1
然后在需要的地方使用
SetEnvIfNoCaseMY_REQUEST_URI_BF_REWRITE"sitemap"...