这个模块允许使用正则表达式重写URI(需PCRE库),并且可以根据相关变量重定向和选择不同的配置。如果这个指令在server字段中指定,那么将在被请求的location确定之前执行,如果在指令执行后所选择的location中有其他的重写规则,那么它们也被执行。如果在location中执行这个指令产生了新的URI,那么location又一次确定了新的URI。这样的循环可以最多执行10次,超过以后nginx将返回500错误。
语法:break  
默认值:none  
使用字段:server, location, if  
完成当前设置的规则,停止执行其他的重写指令。  
示例:
| 1 2 3 4 | if($slow) {  limit_rate  10k;  break;} | 
语法:if (condition) { … }  
默认值:none  
使用字段:server, location  
注意:在使用if指令之前请查看if
 is evil page并且尽量考虑用try_files代替。
  
判断一个条件,如果条件成立,则后面的大括号内的语句将执行,相关配置从上级继承。  
可以在判断语句中指定下列值:
一个变量的名称;不成立的值为:空字符传”“或者一些用“0”开始的字符串。
一个使用=或者!=运算符的比较语句。
使用符号~*和~模式匹配的正则表达式:
~为区分大小写的匹配。
~*不区分大小写的匹配(firefox匹配FireFox)。
!~和!~*意为“不匹配的”。
使用-f和!-f检查一个文件是否存在。
使用-d和!-d检查一个目录是否存在。
使用-e和!-e检查一个文件,目录或者软链接是否存在。
使用-x和!-x检查一个文件是否为可执行文件。
正则表达式的一部分可以用圆括号,方便之后按照顺序用$1-$9来引用。  
示例配置:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | if($http_user_agent ~ MSIE) {  rewrite  ^(.*)$  /msie/$1  break;}                                                                                                                                                       if($http_cookie ~* "id=([^;]
 +)(?:;|$)") {  set$id$1;}                                                                                                                                                       if($request_method = POST ) {  return405;}                                                                                                                                                       if(!-f $request_filename) {  break;  proxy_pass  http://127.0.0.1;}                                                                                                                                                       if($slow) {  limit_rate  10k;}                                                                                                                                                       if($invalid_referer) {  return403;}                                                                                                                                                       if($args ~ post=140){  rewrite ^ http://example.com/
 permanent;} | 
内置变量$invalid_referer用指令valid_referers指定。
语法:return code  
默认值:none  
使用字段:server, location, if  
这个指令结束执行配置语句并为客户端返回状态代码,可以使用下列的值:204,400,402-406,408,410, 411, 413, 416与500-504。此外,非标准代码444将关闭连接并且不发送任何的头部。
语法:rewrite regex replacement flag  
默认值:none  
使用字段:server, location, if  
按照相关的正则表达式与字符串修改URI,指令按照在配置文件中出现的顺序执行。  
可以在重写指令后面添加标记。  
如果替换的字符串以http://开头,请求将被重定向,并且不再执行多余的rewrite指令。  
尾部的标记(flag)可以是以下的值:
last - 完成重写指令,之后搜索相应的URI或location。
break - 完成重写指令。
redirect - 返回302临时重定向,如果替换字段用http://开头则被使用。
permanent - 返回301永久重定向。
注意如果一个重定向是相对的(没有主机名部分),nginx将在重定向的过程中使用匹配server_name指令的“Host”头或者server_name指令指定的第一个名称,如果头不匹配或不存在,如果没有设置server_name,将使用本地主机名,如果你总是想让nginx使用“Host”头,可以在server_name使用“*”通配符(查看http核心模块中的server_name)。例如:
| 1 2 3 | rewrite  ^(/download/.*)/media/(.*)\..*$ 
 $1/mp3/$2.mp3  last;rewrite  ^(/download/.*)/audio/(.*)\..*$ 
 $1/mp3/$2.ra   last;return403; | 
但是如果我们将其放入一个名为/download/的location中,则需要将last标记改为break,否则nginx将执行10次循环并返回500错误。
| 1 2 3 4 5 | location /download/{  rewrite  ^(/download/.*)/media/(.*)\..*$ 
 $1/mp3/$2.mp3  break;  rewrite  ^(/download/.*)/audio/(.*)\..*$ 
 $1/mp3/$2.ra   break;  return403;} | 
如果替换字段中包含参数,那么其余的请求参数将附加到后面,为了防止附加,可以在最后一个字符后面跟一个问号:
| 1 | rewrite  ^/users/(.*)$  /show?user=$1? 
 last; | 
注意:大括号({和}),可以同时用在正则表达式和配置块中,为了防止冲突,正则表达式使用大括号需要用双引号(或者单引号)。例如要重写以下的URL:
| 1 | /photos/123456 | 
为:
| 1 | /path/to/photos/12/1234/123456.png | 
则使用以下正则表达式(注意引号):
| 1 | rewrite  "/photos/([0-9] {2})([0-9] {2})([0-9] {2})"/path/to/photos/$1/$1$2/$1$2$3.png; | 
如果指定一个“?”在重写的结尾,Nginx将丢弃请求中的参数,即变量$args,当使用$request_uri或$uri&$args时可以在rewrite结尾使用“?”以避免nginx处理两次参数串。
  
在rewrite中使用$request_uri将www.example.com重写到example.com:
| 1 2 3 4 | server {   server_name www.example.com;   rewrite ^ http://example.com$request_uri?
 permanent;} | 
同样,重写只对路径进行操作,而不是参数,如果要重写一个带参数的URL,可以使用以下代替:
| 1 2 3 | if($args ^~ post=100){  rewrite ^ http://example.com/new-address.html?
 permanent;} | 
注意$args变量不会被编译,与location过程中的URI不同(参考http核心模块中的location)。
语法:rewrite_log on | off  
默认值:rewrite_log off  
使用字段:server, location, if  
变量:无  
启用时将在error log中记录notice 标记的重写日志。
语法:set variable value  
默认值:none  
使用字段:server, location, if  
指令设置一个变量并为其赋值,其值可以是文本,变量和它们的组合。  
你可以使用set定义一个新的变量,但是不能使用set设置$http_xxx头部变量的值。
语法:uninitialized_variable_warn on|off  
默认值:uninitialized_variable_warn on  
使用字段:http, server, location, if  
开启或关闭在未初始化变量中记录警告日志。  
事实上,rewrite指令在配置文件加载时已经编译到内部代码中,在解释器产生请求时使用。  
这个解释器是一个简单的堆栈虚拟机,如下列指令:
| 1 2 3 4 5 6 7 8 | location /download/{  if($forbidden)
 {    return403;  }  if($slow)
 {    limit_rate  10k;  }  rewrite  ^/(download/.*)/media/(.*)\..*$ 
 /$1/mp3/$2.mp3  break; | 
将被编译成以下顺序:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | variable $forbiddenchecking to zerorecovery 403completion of entire codevariable $slowchecking to zerocheckings of regular excodessioncopying "/"copying $1copying "/mp3/"copying $2copying ".mp3"completion of regular excodessioncompletion of entire sequence | 
注意并没有关于limit_rate的代码,因为它没有提及ngx_http_rewrite_module模块,“if”块可以类似”location”指令在配置文件的相同部分同时存在。  
如果$slow为真,对应的if块将生效,在这个配置中limit_rate的值为10k。  
指令:
| 1 | rewrite  ^/(download/.*)/media/(.*)\..*$ 
 /$1/mp3/$2.mp3  break; | 
如果我们将第一个斜杠括入圆括号,则可以减少执行顺序:
| 1 | rewrite  ^(/download/.*)/media/(.*)\..*$ 
 $1/mp3/$2.mp3  break; | 
之后的顺序类似如下:
| 1 2 3 4 5 6 7 | checking regular excodessioncopying $1copying "/mp3/"copying $2copying ".mp3"completion of regular excodessioncompletion of entire code | 
2.简单案例
注,由于配置文件内容较多,为了让大家看着方便,我们备份一下配置文件,打开一个新的配置文件。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | [root@nginx ~]# cd /etc/nginx/[root@nginx nginx]# mv nginx.conf nginx.conf.proxy[root@nginx nginx]# cp nginx.conf.bak nginx.conf[root@nginx nginx]# vim /etc/nginx/nginx.confserver {      listen       80;      server_name  localhost;      #charset koi8-r;      #access_log  logs/host.access.log  main;      location / {          root   html;          index  index.html index.htm;          rewrite ^/bbs/(.*)$
 http://192.168.18.201/forum/$1;      }} | 
准备forum目录与测试文件
| 1 2 3 4 5 6 7 | [root@web1 ~]# cd /var/www/html/[root@web1 html]# lsindex.html[root@web1 html]# mkdir forum[root@web1 html]# cd forum/[root@web1 forum]# vim index.html<h1>forum page!</h1> | 
测试一下
好了,下面我们来测试一下rewrite重写。
3.重新加载一下配置文件
| 1 2 3 4 | [root@nginx 63]# service nginx reloadnginx: the configuration file/etc/nginx/nginx.conf
 syntax is oknginx: configuration file/etc/nginx/nginx.conf testis
 successful重新载入 nginx:                                           [确定] | 
4.测试一下
注,大家可以从图中看出,status code 302指的是临时重定向,那就说明我们rewrite重写配置成功。大家知道302是临时重定向而301是永久重定向,那么怎么实现永久重定向呢。一般服务器与服务器之间是临时重定向,服务器内部是永久重定向。下面我们来演示一下永久重定向。
5.配置永久重定向
| 1 2 3 4 5 6 7 8 9 10 11 12 | [root@nginx nginx]# vim /etc/nginx/nginx.confserver {        listen       80;        server_name  localhost;        #charset koi8-r;        #access_log  logs/host.access.log  main;        location / {            root   html;            index  index.html index.htm;            rewrite ^/bbs/(.*)$ /forum/$1;        }} | 
准备forum目录与测试文件
| 1 2 3 4 5 6 7 | [root@nginx ~]# cd /usr/html/[root@nginx html]# ls50x.html  index.html[root@nginx html]# mkdir forum[root@nginx html]# cd forum/[root@nginx forum]# vim index.html<h1>192.168.18.208 forum page</h1> | 
6.重新加载一下配置文件
| 1 2 3 4 | [root@nginx ~]# service nginx reloadnginx: the configuration file/etc/nginx/nginx.conf
 syntax is oknginx: configuration file/etc/nginx/nginx.conf testis
 successful重新载入 nginx:                                           [确定] | 
7.测试一下
注,大家从图中可以看到,我们访问bbs/是直接帮我们跳转到forum/下,这种本机的跳转就是永久重定向也叫隐式重定向。好了,rewrite重定向我们就说到这里了,想要查询更多关于重定向的指令请参考官方文档。最后,我们来说一下读写分离。
原文:http://blog.csdn.net/sun5769675/article/details/51760366