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 ; }
当我们请求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; }
当我们请求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; } }
当请求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; } }
当请求/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; } }
当请求/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; } }
当请求/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重新向下去匹配规则,如果没有符合的会继续从头开始。