Nginx 指令之break和last

参考自:https://www.cnblogs.com/xuliangwei/p/11568223.html

两个指令用法相同,但含义不同,需要放到rewrite规则的末尾,用来控制重写后的URL或uri是否继续被h后面的nginx配置执行(主要是rewrite、return指令)。

break 与 last 的区别

     last: 停止当前这个请求,并根据rewrite匹配的规则重新发起一个请求。新请求又从第一阶段开始执行…
  break:相对last,break并不会重新发起一个请求,只是跳过当前的rewrite阶段,并执行本请求后续的执行阶段…

 

示例说明

1、连续两条rewrite规则

server{
    listen 80; 
    server_name test.com;
    root html;

    rewrite /1.html /2.html ;
    rewrite /2.html /3.html ;
    
}
View Code
当我们请求1.html时,最终访问到的是3.html,两条rewrite规则先后执行。

2、break和last 在location {} 外部

server 中没有location

server{
    listen 80; 
    server_name test.com;
    root html;

    rewrite /1.html /2.html break;
    rewrite /2.html /3.html;
}
View Code
当我们请求1.html时,最终访问到的是2.html,说明break在此示例中,作用是不再执行break以下的rewrite规则。注意即使是在同一location内部这种情况也不会执行同一location内部break后面的rewrite等指令。至于不同location 会不会执行下面有说明。

break或last后面还有location时

server{
    listen 80; 
    server_name test.com;
    root html;

    rewrite /1.html /2.html;
    break;
    rewrite /2.html /3.html;     #不执行此处 
   
    location /2.html {              #匹配此处,符合的话执行{}里面配置
        return 403;
    }
}
View Code
当请求1.html时,最终会返回403状态码,说明它去匹配了break后面的location{}配置,(前提是请求要匹配该location)。注意上述两个示例对于last 也是相同的情况。

3、当break在location{}里面

多个rewrite 没有break

server{
    listen 80; 
    server_name test.com;
    root html;
    
    location / {
        rewrite /1.html /2.html;
        rewrite /2.html /3.html;
    }
    location /2.html
    {
        rewrite /2.html /a.html;
    }
    location /3.html
    {
        rewrite /3.html /b.html;
    }
}
View Code

当请求/1.html,最终将会访问/b.html,连续执行location /下的两次rewrite,跳转到了/3.html,然后又匹配location /3.html 

 

location 里面有break

server{
    listen 80; 
    server_name test.com;
    root html;
    
    location / {
        rewrite /1.html /2.html;
        break;
        rewrite /2.html /3.html;
    }
    location /2.html
    {
        rewrite /2.html /a.html;
    }
    location /3.html
    {
        rewrite /3.html /b.html;
    }
}
View Code
当请求/1.html,最终会访问/2.html.在location{}内部,遇到break,本location{}内以及后面的所有location{}内的所有指令都不再执行,注意是不在匹配后面的locatin ,以及不再执行本location里面break后面的rewrite 或 return 等指令,但是如果后面是proxy_pass配置就会执行代理转发。

4、last 在location里面

server{
    listen 80; 
    server_name test.com;
    root html;
    
    location / {
        rewrite /1.html /2.html last;
        rewrite /2.html /3.html;        #此处跳过不执行
    }
    location /2.html
    {
        rewrite /2.html /a.html;
    }
    location /3.html
    {
        rewrite /3.html /b.html;
    }
}
View Code
当请求/1.html,最终会访问/a.html。在location{}内部,遇到last,本location{}内后续指令不再执行,而重写后的url再次从头开始,从头到尾匹配一遍规则。

总结

1、当rewrite规则在location{}外,break和last作用一样,遇到break或last后,其后续的rewrite/return语句不再执行。但后续有location{}的话,还会近一步执行location{}里面的语句,前提是请求必须要匹配该location。

2、当rewrite规则在location{}里,遇到break后,本location{}与其他location{}的所有rewrite/return规则都不再执行,只会执行本location中的root 或者proxypass。

3、当rewrite规则在location{}里,遇到last后,本location{}里后续rewrite/return规则不执行,但重写后的url再次从头开始执行所有规则,哪个匹配执行哪个。

4、break 与 last 的区别:

     last: 停止当前这个请求,并根据rewrite匹配的规则重新发起一个请求。新请求又从第一阶段开始执行…
  break:相对last,break并不会重新发起一个请求,只是跳过当前的rewrite阶段,并执行本请求后续的执行阶段…

5、配置rewrite last时,请求跳出当前location,进入server块,重新进行location匹配,超过10次匹配不到报500错误。客户端的url不变。(未验证过)

注意

rewrite  的执行不会影响浏览器中的请求的url ,现实的还是原来的地址,日志中显示的uri 也是重写之前的uri。

如果rewrite uri 后进行的是proxy_pass 转发,转到另一个nginx 服务器后,该nginx 日志记录的是重写后的uri。

没有break的rewrite 可能会产生死循环,因为请求被rewrite 后会新的URL重新向下去匹配规则,如果没有符合的会继续从头开始。

posted @ 2020-03-01 16:10  fanggege  阅读(4114)  评论(0编辑  收藏  举报