在nginx中使用多个条件进行rewrite
原文地址:http://www.blogkid.net/archives/2358.html
买了VPS以后,不甘只用apache。于是我换上了nginx做Web Server。但原来rewrite规则需要“翻译”成nginx的语法,这里就出了问题。我的blog使用着supercache,另一个网站使用了类似的静态缓存(请看我另一篇文章:8行代码实现supercache)。问题出在哪里呢?supercache的实现方式,是基于多组合条件的rewrite,但nginx恰恰不支持嵌套的或并列的 if 判断语句,于是没法直接支持多条件的rewrite。
比如,在apache中使用supercache时一段配置是这么写的:
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{QUERY_STRING} !.*s=.*
RewriteCond %{QUERY_STRING} !.*p=.*
……
RewriteRule ^(.*) /wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html.gz [L]
可以看到,apache在经过一大堆RewriteCond的判断后,才进行rewrite。但在nginx中,无法这么写:
if ($request_method !~ ^post$ && $request_filename !~ .*s=.* …) {
rewrite …
}
一时没想到好办法,直到找到一篇文章: nginx rewrite rules for WordPress + WP Super Cache,豁然开朗:虽然没有嵌套的if,但是可以用set语句为一个变量赋值,这样,就可以设置一个变量作为标志位。看看在这种思路指导下的配置:
set $supercache_file '';
set $supercache_uri $request_uri;if ($request_method = POST) {
set $supercache_uri ”;
}# Using pretty permalinks, so bypass the cache for any query string
if ($query_string) {
set $supercache_uri ”;
}…
if ($supercache_uri ~ ^(.+)$) {
set $supercache_file /blog/wp-content/cache/supercache/$http_host/$1index.html;
}
if (-f $document_root$supercache_file) {
rewrite ^(.*)$ $supercache_file break;
}
将一个名为$supercache_uri的变量作为标志位,如果不满足一些前置条件时,将标志位置空;在最后只要判断标志位是否为空,如果不为空,再进行rewrite。妙极。
使用这种方法,足以使nginx应对多个条件下进行rewrite的场景,只是写起来有点麻烦。不知道nginx有没有打算让 if 判断语句在将来的版本中可以嵌套呢?
BTW,passenger for nginx横空出世,抽空可以玩玩。


nginx下WordPress的rewrite规则,如果访问不是wp开头的文件,就会调到404~
你的会吗?
@mao
不会啊
rewrite之前需要先判断一下是否有这个文件,不管是不是wp开头都没关系的。
我也豁然开朗了。
有空也玩玩nginx
请问博主能帮忙一下么?我用Nginx,按照网上的方法配置好了wp super cache,但是后台无论怎么设置,每次评论以后,都得等待缓存页面删除了才能显示,汗……
你是不是勾选了 enable lockdown?
passenger for nginx…中文文章太少了..
强烈要求你出小白兔文章~
@mao
你自己先玩玩吧,我反正是没搞成功
看了之后还是不明白,是不是每个语句都要加一个if判断???
谢谢。终于找到解决方法了。
好文章,谢谢了,我也解决了我的问题,nginx还是应该把if判断加强一些