rewrite指令解析

来源:互联网 发布:excel找相同数据if 编辑:程序博客网 时间:2024/06/06 02:12

 

在官网上,rewrite指令的语法规则如下:

Syntax:

rewriteregex replacement [flag];

Default:

Context:

server,location,if

 

可选项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.

 

在这里特别要注意的是lastbreak的区别,同时还要注意在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指令。

 

这里做一下总结:last其实就相当于一个新的url,“似乎”对nginx进行了一次新的请求,又需要走一遍大多数的处理过程,最重要的是会做一次find config,提供了一个可以转到其他location的配置中处理的机会(本质就是实现了内部的重定向),而break则是在一个请求处理过程中将原来的url(包括uri和args)改写之后,再继续进行后面的处理,这个重写之后的请求始终都是在同一个location中处理。

 

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

2)《Nginx Rewrite研究笔记

http://blog.cafeneko.info/2010/10/nginx_rewrite_note/

 

0 0