nginx last break等
rewrite的规则可以在server或者location模块下,如果在server下匹配,则需要将rewrite之后的uri继续向下匹配location,如果在location模块内有rewrite,匹配后,需要将rewrite之后的uri继续在location模块内向下匹配,如果在模块内没有匹配,则重新走一遍所有匹配
1.rewrite xxx xxx last,则不匹配location内部其他rewrite,但是需要继续匹配其他location模块
2.break,直接不再和其他模块匹配
Break 和 last 都能阻止继续执行后面的 rewrite 指令,但是 last 如果在 location 下用的话,对于重写后的 URI 会重新匹配 location ,但是 break 则不会重新匹配 location 。简单的说, break 终止的力度比last 更加彻底(为了记忆的方便,我们可以把重新后的 URI 重新匹配 location 理解为“ URI 匹配 location 的循环语句的下一次迭代”,高级程序设计里面 break 一般用做退出循环,所以 break 不仅终止继续执行 rewrite ,而且退出 URI 重新匹配 location 的循环迭代)。
配置:
error_log logs/error.log info;
server {
listen 9090;
server_name localhost;
root html;
rewrite_log on;
rewrite "^/aaa\.html$" /bbb.html;
rewrite "^/ccc\.html$" /ddd.html;
location /bbb.html {
rewrite "^/bbb\.html$" /ccc.html;
}
location /ddd.html {
rewrite "^/ddd\.html$" /eee.html;
}
}
结果:
[root@web108 ~]# curl http://localhost:9090/aaa.html
eee html file
[root@web108 ~]#
日志:
2011/08/08 10:21:00 [notice] 2218#0: *91 "^/aaa\.html$" matches "/aaa.html" , client: 127.0.0.1, server: localhost, request: "GET /aaa.html HTTP/1.1", host: "localhost:9090"
2011/08/08 10:21:00 [notice] 2218#0: *91 rewritten data: "/bbb.html" , args: "", client: 127.0.0.1, server: localhost, request: "GET /aaa.html HTTP/1.1", host: "localhost:9090"
2011/08/08 10:21:00 [notice] 2218#0: *91 "^/ccc\.html$" does not match "/bbb.html" , client: 127.0.0.1, server: localhost, request: "GET /aaa.html HTTP/1.1", host: "localhost:9090"
2011/08/08 10:21:00 [notice] 2218#0: *91 "^/bbb\.html$" matches "/bbb.html" , client: 127.0.0.1, server: localhost, request: "GET /aaa.html HTTP/1.1", host: "localhost:9090"
2011/08/08 10:21:00 [notice] 2218#0: *91 rewritten data: "/ccc.html" , args: "", client: 127.0.0.1, server: localhost, request: "GET /aaa.html HTTP/1.1", host: "localhost:9090"
2011/08/08 10:21:00 [notice] 2218#0: *91 "^/aaa\.html$" does not match "/ccc.html" , client: 127.0.0.1, server: localhost, request: "GET /aaa.html HTTP/1.1", host: "localhost:9090"
2011/08/08 10:21:00 [notice] 2218#0: *91 "^/ccc\.html$" matches "/ccc.html" , client: 127.0.0.1, server: localhost, request: "GET /aaa.html HTTP/1.1", host: "localhost:9090"
2011/08/08 10:21:00 [notice] 2218#0: *91 rewritten data: "/ddd.html" , args: "", client: 127.0.0.1, server: localhost, request: "GET /aaa.html HTTP/1.1", host: "localhost:9090"
2011/08/08 10:21:00 [notice] 2218#0: *91 "^/ddd\.html$" matches "/ddd.html" , client: 127.0.0.1, server: localhost, request: "GET /aaa.html HTTP/1.1", host: "localhost:9090"
2011/08/08 10:21:00 [notice] 2218#0: *91 rewritten data: "/eee.html" , args: "", client: 127.0.0.1, server: localhost, request: "GET /aaa.html HTTP/1.1", host: "localhost:9090"
2011/08/08 10:21:00 [notice] 2218#0: *91 "^/aaa\.html$" does not match "/eee.html" , client: 127.0.0.1, server: localhost, request: "GET /aaa.html HTTP/1.1", host: "localhost:9090"
2011/08/08 10:21:00 [notice] 2218#0: *91 "^/ccc\.html$" does not match "/eee.html" , client: 127.0.0.1, server: localhost, request: "GET /aaa.html HTTP/1.1", host: "localhost:9090"
2011/08/08 10:21:00 [info] 2218#0: *91 client 127.0.0.1 closed keepalive connection
解释:
第一次迭代 location 匹配
GET /aaa.html ,首先执行 server 级的重写,“ rewrite "^/aaa\.html$" /bbb.html ”把 /aaa.html 重写为 /bbb.html ,但 /bbb.html 没匹配上“ rewrite "^/ccc\.html$" /ddd.html ”,最终保留 /bbb.html ;接着,匹配 location /bbb.html {},执行 location 级的 rewrite 指令,把 /bbb.html 重写为 /ccc.html ,由于 URI 被 location 级 rewrite 重写,因此需要重新迭代 location 匹配。
第二次迭代 location 匹配
对于第一次迭代结果 /ccc.html ,首先依然是执行 server 级的 rewrite 指令,“ rewrite "^/aaa\.html$" /bbb.html;”跟 /ccc.html 不匹配,但“ rewrite "^/ccc\.html$" /ddd.html; ”把 /ccc.html 重写为 /ddd.html ; server 级 rewrite 执行完后,接着 location 匹配, /ddd.html 匹配到 location /ddd.html {} ,执行 location 级的 rewrite 指令,把/ddd.html 重写为 /eee.html 。同样由于 URI 被 location 级的 rewrite 指令重写,于是需要重新迭代 location 匹配。
第三次迭代 location 匹配
对于第二次迭代结果 /eee.html ,首先依然执行 server 级的 rewrite 指令,“ rewrite "^/aaa\.html$" /bbb.html; ”和“rewrite "^/ccc\.html$" /ddd.html; ”,只不过它们都没匹配上 /eee.html ,接着 /eee.html 进行 location 匹配,也没有,最终结果是 /eee.html ,返回“ eee html file ”页面。