http://blog.csdn.net/weiyuefei/article/details/38089221
在官网上,rewrite指令的语法规则如下:
Syntax: | |
---|---|
Default: | — |
Context: | |
可选项flag可以有四种可能的取值:last,break,redirect,permanent。
1.last
stops processing the current set of ngx_http_rewrite_module directives followed by a search for a new location matching the changed URI;
2.break
stops processing the current set of ngx_http_rewrite_module directives;
3.redirect
returns a temporary redirect with the 302 code; used if a replacement string does not start with “http://” or “https://”;
4.permanent
returns a permanent redirect with the 301 code.
在这里特别要注意的是last和break的区别,同时还要注意在server域和location域下用法的不同。
如果是在server域下,那么last和break的作用是一样的,那就是跳过server域下其他rewrite指令的执行。注意,仅仅是server域下的,如果匹配了location,而location下也有rewrite指令,那么location下的rewrite指令还是会被执行。
如果是在location域下,那么last和break的区别是:如果把其所在location比作一个循环,那么last就相当于continue语句,即跳过location中剩余的指令,重新匹配location;break就相当于break语句,会直接跳出循环,在这里跳出循环的意思就是不会去重新匹配location,而是直接在当前location下执行,但是不会去执行当前location下其他的rewrite指令。
redirect和permanent都是会给终端返回一个重定向的URL,主要区别是前者返回302的状态码,后者返回301.
最后贴一下从一个大牛博客上摘录的关于rewrite执行过程的伪代码的描述:
boolean match_finish = false;
int match_count = 0;
while (!match_finish && match_count < 10) {
match_count++;
(1)按编辑顺序执行server级的rewrite指令;
(2)按重写后的URI匹配location;
(3)string uri_before_location = uri;
按编辑顺序执行location级的rewrite指令;
string uri_after_location = rewrite(uri);
if (uri_before_location != uri_after_location) {
match_finish = false;
} else {
match_finish = true;
}
if (location rewrite has last flag) {
continue;//表示不执行后面的rewrite,直接进入下一次迭代
}
if (location rewrite has break flag) {
break;//表示不执行后面的rewrite,并退出循环迭代
}
}
if(match_count <= 10) {
return HTTP_200;
} else {
return HTTP_500;
}
关于rewrite更详细的描述,可参考:
1)《Nginx关于Rewrite执行顺序详解 》
http://eyesmore.iteye.com/blog/1142162
http://blog.cafeneko.info/2010/10/nginx_rewrite_note/