Nginx配置的rewrite编写时last与break的区别详解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx配置的rewrite编写时last与break的区别详解相关的知识,希望对你有一定的参考价值。

rewite

1. server块中的rewrite:

在server块下,会优先执行rewrite部分,然后才会去匹配location块
server中的rewrite break和last没什么区别,都会去匹配location,所以没必要用last再发起新的请求,可以留空。


2. location中的rewirte:

不写last和break -    那么流程就是依次执行这些rewrite
1. rewrite break -        url重写后,直接使用当前资源,不再执行location里余下的语句,完成本次请求,地址栏url不变
2. rewrite last -        url重写后,马上发起一个新的请求,再次进入server块,重试location匹配,超过10次匹配不到报500错误,地址栏url不变
3. rewrite redirect –    返回302临时重定向,地址栏显示重定向后的url,爬虫不会更新url(因为是临时)

4. rewrite permanent –    返回301永久重定向, 地址栏显示重定向后的url,爬虫更新url


这篇文章主要介绍了nginx配置的rewrite编写时last与break的区别分析,简单来说使用last会对server标签重新发起请求,而break就直接使用当前的location中的数据源来访问,需要的朋友可以参考下:

location /  
{  
  proxy_pass http://test;  
  alias /home/html/;  
  root /home/html;  
  rewrite "^/a/(.*)\.html$" /1.html last;  
}

在location / { 配置里:
1、使用root指定源:使用last和break都可以
2、使用proxy_pass指定源:使用last和break都可以
3、使用alias指定源:必须使用last
在location /a/或使用正则的location ~ ^/a/里:
1、使用root指定源:使用last和break都可以
2、使用proxy_pass指定源:使用break和last结果有所区别
3、使用alias指定源:必须使用last
其中区别主要在proxy_pass这个标签上,再看看几个测试结果:

location /  
{  
  root /home/html;  
}  
  
location /a/  
{  
  proxy_pass http://test;  
  rewrite "^/a/(.*)\.html$" /1.html last;  
}

在这段配置里,使用last访问是可以访问到东西的,不过,它出来的结果是:/home/html/1.html;可我需要的是http://test/1.html?使用break就可以了。

location /  
{  
  root /home/html;  
}  
   
location /a/  
{  
  proxy_pass http://test;  
  rewrite "^/a/(.*)\.html$" /a/1.html last;  
}

在这段配置里,返回错误,因为last会重新发起请求匹配,所以造成了一个死循环,使用break就可以访问到http://test/a/1.html。
所以,使用last会对server标签重新发起请求,而break就直接使用当前的location中的数据源来访问,要视情况加以使用。一般在非根的location中配置rewrite,都是用的break;而根的location使用last比较好,因为如果配置了fastcgi或代理访问jsp文件的话,在根location下用break是访问不到。测试到rewrite有问题的时候,也不妨把这两者换换试试。
至于使用alias时为什么必须用last,估计是nginx本身就限定了的,怎么尝试break都不能成功。

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

我们再来看一个例子:

server {
  listen 80 default_server;
  server_name dcshi.com;
  root www;
 
  location /break/ {
    rewrite ^/break/(.*) /test/$1 break;
    echo "break page";
  } 
 
  location /last/ {
     rewrite ^/last/(.*) /test/$1 last;
     echo "last page";
  }  
 
  location /test/ {
    echo "test page";
  }
}

请求:http://dcshi.com/break/***
输出: break page
分析:正如上面讨论所说,break是跳过当前请求的rewrite阶段,并继续执行本请求的其他阶段,很明显,对于/foo 对应的content阶段的输出为 echo “break page”; (content阶段,可以简单理解为产生数据输出的阶段,如返回静态页面内容也是在content阶段;echo指令也是运行在content阶段,一般情况下content阶段只能对应一个输出指令,如同一个location配置两个echo,最终只会有一个echo指令被执行);当然如果你把/break/里的echo 指令注释,然后再次访问/break/xx会报404,这也跟我们预期一样:虽然/break/xx被重定向到/test/xx,但是break指令不会重新开启一个新的请求继续匹配,所以nginx是不会匹配到下面的/test/这个location;在echo指令被注释的情况下,/break/ 这location里只能执行nginx默认的content指令,即尝试找/test/xx这个html页面并输出起内容,事实上,这个页面不存在,所以会报404的错误。

注意:

使用last和break实现URI重写,浏览器地址栏不变。而且两者有细微差别,使用alias指令必须用last标记;使用proxy_pass指令时,需要使用break标记。Last标记在本条rewrite规则执行完毕后,会对其所在server{......}标签重新发起请求,而break标记则在本条规则匹配完成后,终止匹配。

一般在跟location中(location /{...})或直接在server标签中编写rewrite规则,推荐使用last标记;在非根location中(location /cms/{...}),则使用break。

如果URI中含有参数(/app/test.php?id=5),默认情况下参数会被自动附加到替换串上,你可以通过在替换串的末尾加上?标记来解决这一问题。

本文出自 “zhaoyfcomeon-成长之路” 博客,请务必保留此出处http://zhaoyfcomeon.blog.51cto.com/8429349/1964584

以上是关于Nginx配置的rewrite编写时last与break的区别详解的主要内容,如果未能解决你的问题,请参考以下文章

nginx配置指令rewrite的last、break、redirect、permanent参数详解

nginx rewrite的break与last区别 小记

Nginx学习笔记17rewrite之last

Nginx rewrite 中break与last指令的区别

nginx thinkphp5 多入口配置

lnmp集成环境tp nginx vhost配置