Nginx配置的rewrite编写时last与break的区别分析

在使用nginx配置rewrite中经常会遇到有的地方用last并不能工作,换成break就可以,其中的原理是对于根目录的理解有所区别,按我的测试结果大致是这样的。

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的错误。

(0)

相关推荐

  • Nginx下配置pathinfo及ThinkPHP的URL Rewrite模式支持

    打开Nginx的配置文件 /usr/local/nginx/conf/nginx.conf 一般是在这个路径,根据你的安装路径可能有所变化.如果你配置了vhost,而且只需要你这一个vhost支持pathinfo的话,可以直接打开你的vhost的配置文件.找到类似如下代码(不同版本的nginx可能稍有不同,但是相差不会很远): 复制代码 代码如下: location ~ .*.(php|php5)?$         {                 #原有代码         } 修改成以下

  • nginx rewrite 伪静态配置参数详细说明

    正则表达式匹配,其中: * ~ 为区分大小写匹配 * ~* 为不区分大小写匹配 * !~和!~*分别为区分大小写不匹配及不区分大小写不匹配 文件及目录匹配,其中: * -f和!-f用来判断是否存在文件 * -d和!-d用来判断是否存在目录 * -e和!-e用来判断是否存在文件或目录 * -x和!-x用来判断文件是否可执行 flag标记有: * last 相当于Apache里的[L]标记,表示完成rewrite * break 终止匹配, 不再匹配后面的规则 * redirect 返回302临时重

  • nginx rewrite 伪静态配置参数和使用例子

    正则表达式匹配,其中: * ~ 为区分大小写匹配 * ~* 为不区分大小写匹配 * !~和!~*分别为区分大小写不匹配及不区分大小写不匹配 文件及目录匹配,其中: * -f和!-f用来判断是否存在文件 * -d和!-d用来判断是否存在目录 * -e和!-e用来判断是否存在文件或目录 * -x和!-x用来判断文件是否可执行 flag标记有: * last 相当于Apache里的[L]标记,表示完成rewrite * break 终止匹配, 不再匹配后面的规则 * redirect 返回302临时重

  • nginx 伪静态化rewrite规则

    复制代码 代码如下: location / { ###以下为PHPCMS 伪静态化rewrite规则 rewrite ^(.*)show-([0-9]+)-([0-9]+)\.html$ $1/show.php?itemid=$2&page=$3; rewrite ^(.*)list-([0-9]+)-([0-9]+)\.html$ $1/list.php?catid=$2&page=$3; rewrite ^(.*)show-([0-9]+)\.html$ $1/show.php?spe

  • Ubuntu下Nginx配置ThinkPHP的Pathinfo和URl Rewrite模式

    概述 在上一篇文章Nginx配置Thinkphp支持URL Rewrite中已经介绍了如何配置Nginx支持ThinkPHP的URL Rewrite,但是上文针对的是Centos平台,这次因为某些特殊的原因,服务器环境必须用ubuntu,本来以为和Cetons中一模一样,但是配置完了发现不能使用,所以就百度了一些文章. 配置方法 TP官方解决方案 复制代码 代码如下: location ~ .php         {                 #原有代码                

  • nginx重写rewrite基础及实例分享

    nginx rewrite 正则表达式匹配 大小写匹配 ~ 为区分大小写匹配 ~* 为不区分大小写匹配 !~和!~*分别为区分大小写不匹配及不区分大小写不匹配 文件及目录匹配 -f和!-f用来判断是否存在文件 -d和!-d用来判断是否存在目录 -e和!-e用来判断是否存在文件或目录 -x和!-x用来判断文件是否可执行 flag标记 last 相当于Apache里的[L]标记,表示完成rewrite break 终止匹配, 不再匹配后面的规则. redirect 返回302临时重定向 地址栏会显示

  • Nginx配置PHP的Yii与CakePHP框架的rewrite规则示例

    Yii的Nginx rewrite 如下为nginx yii的重写 server { set $host_path "/data/site/www.jb51.net"; access_log /data/logs/nginx/www.jb51.net_access.log main; server_name jb51.net www.jb51.net; root $host_path/htdocs; set $yii_bootstrap "index.php"; #

  • 浅谈apache和nginx的rewrite的区别

    1. Nginx Rewrite规则相关指令 Nginx Rewrite规则相关指令有if.rewrite.set.return.break等,其中rewrite是最关键的指令.一个简单的Nginx Rewrite规则语法如下: rewrite ^/b/(.*)\.html /play.php?video=$1 break; 如果加上if语句,示例如下: if (!-f $request_filename) { rewrite ^/img/(.*)$ /site/$host/images/$1

  • Nginx Rewrite规则与使用介绍和技巧实例

    一.正则表达式匹配,其中: * ~ 为区分大小写匹配 * ~* 为不区分大小写匹配 * !~和!~*分别为区分大小写不匹配及不区分大小写不匹配 二.文件及目录匹配,其中: * -f和!-f用来判断是否存在文件 * -d和!-d用来判断是否存在目录 * -e和!-e用来判断是否存在文件或目录 * -x和!-x用来判断文件是否可执行 三.rewrite指令的最后一项参数为flag标记,flag标记有: 1.last 相当于apache里面的[L]标记,表示rewrite. 2.break本条规则匹配

  • Nginx伪静态配置和常用Rewrite伪静态规则集锦

    nginx里使用伪静态是直接在nginx.conf 中写规则的,并不需要像apache要开启写模块(mod_rewrite)才能进行伪静态. nginx只需要打开nginx.conf配置文件,在server里面写需要的规则即可. 复制代码 代码如下: server { listen       80; server_name  bbs.jb51.net; index index.html index.htm index.php; root  /home/www/bbs; error_page 

  • Nginx下支持Thinkphp URL Rewrite的配置示例

    概述 Nginx服务器现在已经成为相当流行的开源Web服务器,很多生产环境也都在使用Nginx服务器.现在做项目大多数时候都是在使用ThinkPHP,但是Nginx默认不支持ThinkPHP的pathinfo模式,需要进行一定的配置. Nginx配置文件 # # The default server # server { listen 80 default_server; #server_name www.example.com; #charset koi8-r; #access_log log

  • Nginx的伪静态配置中使用rewrite来实现自动补全的实例

    nginx+php 使用的时候经常需要伪静态,一般大家都手动设置.那有没有办法让 nginx 自动补全路径呢? 这两天折腾很久,才实现了这样一个功能: 请求 /a/b/c 若文件不存在,查找 /a/b/index.php,/c 作为 PATH_INFO: 若文件不存在,查找 /a/index.php,/b/c 作为 PATH_INFO: 若文件不存在,查找 /index.php,/a/b/c 作为 PATH_INFO: 若文件不存在,返回 404. 虽然这种损耗性能的行为不适合部署,但在本机调试

  • Nginx服务器下使用rewrite重写url以实现伪静态的示例

    经过网上查阅和测试,发现Nginx的Rewrite规则和Apache的Rewite规则差别不是很大,几乎可以直接使用.比如在Apache中这样写规则 rewrite ^/([0-9]{5}).html$ /viewthread.php?tid=$1 last; 而在Nginx中写成这样写是无法启动的,解决的办法是加上两个双引号: rewrite "^/([0-9]{5}).html$" /viewthread.php?tid=$1 last; 同时将RewriteRule为Rewrit

  • WordPress与Drupal的Nginx配置rewrite重写规则示例

    WordPress wordpress依然是目前是世界上最流行的博客系统,越来越多由wordpress搭建而成的网站在使用nginx服务器软件,这里就来分享一下WordPress的nginx重写规则: server { listen 80; server_name www.jb51.net jb51.net; access_log /data/logs/nginx/www.jb51.net.access.log main; index index.html index.php; root /da

随机推荐