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),默认情况下参数会被自动附加到替换串上,你可以通过在替换串的末尾加上?标记来解决这一问题。

时间: 2024-08-07 20:08:45

Nginx配置的rewrite编写时last与break的区别详解的相关文章

nginx配置if错误语句时出错一例

server{ if (!-e $request_filename)        {                rewrite ^(.*)$ /index.php last;        } } 如果if 没有放在location时,在做memc缓存时,在错误日志里会提示以下信息 2014/05/12 10:45:51 [error] 11520#0: *325726 srcache_fetch: cache sent truncated response body while send

python编写微信公众号首图思路详解

前言 之前一直在美图秀秀调整自己的微信公众号首图,效果也不尽如人意,老是调来调去,最后发出来的图片被裁剪了一大部分,丢失部分关键信息,十分恼火,于是想着用python写一个程序,把微信公众号首图的模式固定下来,方便以后写公众号. 思路 根据微信公众号首图要求,可以上传一个不超过5M的图片,且图片尺寸要是2.35:1的尺寸,换算成像素是900:383,有了这些参数就可以做文章了,这里有两种思路 把今天推文的标题(文字)用图片展示出来,使得文字排列错落有致,简单粗暴,而又不失美感,这里可以利用mat

nginx配置ThinkPHP Rewrite

server { listen 80; server_name www.funsion.com; root /www/web/funsion; index index.php; # 禁止访问应用目录中的php文件 location ~* ^/application/.+\.php$ { #此目录下的.html要允许访问,因为静态html缓存也是在这个目录下生成 return 403; } location ~* ^/application/Tpl/.+\.html$ { return 403;

nginx 配置 ThinkPHP Rewrite

server { listen 80; server_name www.funsion.com; root /www/web/funsion; index index.php; location / { # 不带www的时候,自动加上www if ($host !~ '^www') { rewrite "^/(.*)$" http://www.$host/$1 permanent; } if (!-e $request_filename){ rewrite ^/(.*)$ /index

nginx 配置proxy_pass URL末尾加与不加/(斜线)的区别

nginx在配置proxy_pass的时候 URL结尾加斜线(/)与不加的区别和注意事项 假设访问路径的 /pss/bill.html 加/斜线的情况 location /pss/ { proxy_pass http://127.0.0.1:18081/; } 被代理的真实访问路径为:http://127.0.0.1:18081/bill.html  不加/斜线的情况 location /pss/ { proxy_pass http://127.0.0.1:18081; } 被代理的真实访问路径

网络配置命令,绑定,接口命名以及配置文件的详解

一:三大命令家族 当我们在centos中管理网络时需要为网卡设置网络属性,有自动获取和手动配置两种,自动获取需要在主机所在的网络中至少有一台DHCP服务器,而手动配置即静态指定则可以使用命令或者修改配置文件,首先着重说一下使用命令,命令包括net-tools家族(ifcfg家族).iproute家族.nm家族:Network Manager,这三个工具都是setup的子命令,在centos6中可以使用上述命令. 具体命令的总结为: net-tools家族(ifcfg家族) ifconfig接口配

使用vs code编写Markdown文档以及markdown语法详解

目录 首先安装vscode工具,下载地址如下: https://code.visualstudio.com/ 在vs code的扩展中安装: Markdown Preview Enhanced 这款插件,安装完成重新加载即可生效 新建一个.md文件 Visual Studio Code 原生就支持高亮Markdown的语法,想要一边编辑一遍预览,有两种方法: 3.1. Ctrl + Shift + P 调出主命令框,输入 Markdown,应该会匹配到几项 Markdown相关命令 2.2. 先

C/C++程序终止时执行的函数——atexit()函数详解

很多时候我们需要在程序退出的时候做一些诸如释放资源的操作,但程序退出的方式有很多种,比如main()函数运行结束.在程序的某个地方用exit()结束程序.用户通过Ctrl+C或Ctrl+break操作来终止程序等等,因此需要有一种与程序退出方式无关的方法来进行程序退出时的必要处理.方法就是用atexit()函数来注册程序正常终止时要被调用的函数. atexit()函数的参数是一个函数指针,函数指针指向一个没有参数也没有返回值的函数.atexit()的函数原型是:#include <cstdlib

用PHP上传文件时$_FILES中error返回值详解

用PHP上传文件时,我们会用程序去监听浏览器发送过来的文件信息,首先会通 过$_FILES[fieldName]['error']的不同数值来判断此欲上传的文件状态是否正常.$_FILES[fieldName] ['error']==0代表一切正常,其它数值的具体含义请参考下面一段程序的注释部分,如有翻译不到之处还望指正! switch($_FILES[$field]['error']) { case 1:            // 文件大小超出了服务器的空间大小            $th