nginx rewrite规则相关指令的用法,并介绍了nginx下的rewrite和apache的rewrite规则的区别,nginx与apache的rewrite规则实例对比,帮助大家深入理解nginx rewrite规则的配置细节。
nginx rewrite重写规则相关指令
nginx rewrite规则相关指令有if、rewrite、set、return、break等,其中rewrite是最关键的指令。
一般在线上网络,rewrite规则都是搭配if等语句一起是实现的。
例如:
复制代码 代码示例:
if ($host ~* "^baomihua.jb200.com" ) {
rewrite "^/([0-9]+).html(?.+)*$" /show.php?contentid=$1&tpl=1 last;
rewrite "^/([0-9]+)_([0-9]+).html(?.+)*$" /show.php?contentid=$1&vod=$2&tpl=1 last;
rewrite "^/(.*).html(?.+)*$" http://www.jb200.com/$1.html$2 permanent;
rewrite "^/(.+/)*(?.+)*$" http://www.jb200.com/$1$2 permanent;
}
以上配置说明,主机头带有‘baomihua.jb200.com’的将会使用下面的rewrite规则。
而且一般在主机名前面加上“^” 代表以** 开头。
以下nginx rewrite规则则代表:
rewrite "^/([0-9]+).html(?.+)*$" /show.php?contentid=$1&tpl=1 last;
把baomihua.jb200.com/([0-9]+).html(?.+)*$ 重定向到 baomihua.jb200.com/show.php?contentid=$1&tpl=1 ,后面的“([0-9]+)”类似的正则则代表这个主机名后面文件的一切可能的字符,当然这个不是唯一的,可以根据你的网站需求来做。
这个if规则可以多次使用。
也可以直接以一级域名来定义“host”
if ($host ~* "^jb200.com" ) {
rewrite "^/$" http://www.jb200.com/ permanent;
rewrite "^/(.+)$" http://www.jb200.com/$1 permanent;
}
而像以下这种的针对请求文件名字的,是更为常见:
if ( !-f $request_filename ){
rewrite "^/api/player/data/([0-9]+).xml$" /api/player/vod.php?contentid=$1 permanent;
rewrite "^/api/player/configure/([a-z]+).xml$" /api/player/configure.php?contentid=$1 permanent;
rewrite "^/api/webapp/category/xml/category.xml$" /api/webapp/category/index.php permanent;
rewrite "^/api/webapp/list/xml/([0-9+])-([0-9+])-([0-9+])-([0-9+])-([0-9+])-([0-9+]).xml$" /api/webapp/list/list.php?catid=$1&year=$2&area=$3&age=$4&language=$5&page=$6 permanent;
}
if ($request_uri ~* "^/search/?type=([a-z]+)&q=(.*)") {
set $myarg1 $2;
rewrite .* http://so.jb200.com/list.php?q=$myarg1? permanent;
}
这个是最为常见的,以请求的文件名,作为规则来进行转换的。
下面看下nginx下的rewrite和apache的rewrite规则的区别。
二、nginx与apache的rewrite规则实例对比
简单的nginx和apache重写规则区别不大,基本上能够完全兼容。例如:
1、apache rewrite 规则:
RewriteRule ^/(mianshi|xianjing)/$ /zl/index.php?name=$1 [L]
RewriteRule ^/ceshi/$ /zl/ceshi.php [L]
RewriteRule ^/(mianshi)_([a-zA-Z]+)/$ /zl/index.php?name=$1_$2 [L]
RewriteRule ^/pingce([0-9]*)/$ /zl/pingce.php?id=$1 [L]
2、nginx rewrite 规则:
rewrite ^/(mianshi|xianjing)/$ /zl/index.php?name=$1 last;
rewrite ^/ceshi/$ /zl/ceshi.php last;
rewrite ^/(mianshi)_([a-zA-Z]+)/$ /zl/index.php?name=$1_$2 last;
rewrite ^/pingce([0-9]*)/$ /zl/pingce.php?id=$1 last;
由以上示例可以看出,apache的rewrite规则改为nginx的rewrite规则,其实很简单:
apache的rewriterule指令换成nginx的rewrite指令,apache的[l]标记换成nginx的last标记,中间的内容不变。
如果apache的rewrite规则改为nginx的rewrite规则后,使用nginx -t命令检查发现nginx.conf配置文件有语法错误,那么可以尝试给条件加上引号。
例如,以下nginx rewrite规则会报语法错误:
rewrite ^/([0-9]{5}).html$ /x.jsp?id=$1 last;
加上引号就正确了:
rewrite “^/([0-9]{5}).html$” /x.jsp?id=$1 last;
apache与nginx的rewrite规则在url跳转时有细微的区别:
apache rewrite 规则:
RewriteRule ^/html/tagindex/([a-zA-Z]+)/.*$ /$1/ [R=301,L]
nginx rewrite 规则:
rewrite ^/html/tagindex/([a-zA-Z]+)/.*$ http://$host/$1/ permanent;
以上示例中,注意到,Nginx Rewrite 规则的置换串中增加了“http://$host”,这是在Nginx中要求的。
另外,Apache与Nginx的Rewrite规则在变量名称方面也有区别,例如:
apache rewrite 规则:
RewriteRule ^/user/login/$ /user/login.php?login=1&forward=http://%{HTTP_HOST} [L]
nginx rewrite 规则:
rewrite ^/user/login/$ /user/login.php?login=1&forward=http://$host last;
Apache与Nginx Rewrite 规则的一些功能相同或类似的指令、标记对应关系:
Apache的RewriteCond指令对应Nginx的if指令;
Apache的RewriteRule指令对应Nginx的rewrite指令;
Apache的[R]标记对应Nginx的redirect标记;
Apache的[P]标记对应Nginx的last标记;
Apache的[R,L]标记对应Nginx的redirect标记;
Apache的[P,L]标记对应Nginx的last标记;
Apache的[PT,L]标记对应Nginx的last标记;
允许指定的域名访问本站,其他域名一律跳转到http://www.aaa.com
Apache Rewrite 规则:
RewriteCond %{HTTP_HOST} ^(.*?).domain.com$
RewriteCond %{HTTP_HOST} !^qita.domain.com$
RewriteCond %{DOCUMENT_ROOT}/market/%1/index.htm -f
RewriteRule ^/wu/$ /market/%1/index.htm [L]
nginx的if指令不支持嵌套,也不支持and、or等多条件匹配,相比于apache的rewritecond,可以通过下一页的nginx配置写法来实现:
nginx rewrite 规则:
复制代码 代码示例:
if ($host ~* ^(.*?).domain.com$)
{
set $var_wupin_city $1;
set $var_wupin ‘1′;
}
if ($host ~* ^qita.domain.com$)
{
set $var_wupin ‘0′;
}
if (!-f $document_root/market/$var_wupin_city/index.htm)
{
set $var_wupin ‘0′;
}
if ($var_wupin ~ ‘1′)
{
rewrite ^/wu/$ /market/$var_wupin_city/index.htm last;
}