nginx url重写:break和last之间的区别


45

我不明白break和last(重写标志)之间的区别。该文档相当抽象。我已经尝试在某些配置中在两者之间切换,但是我没有发现任何行为上的差异。有人可以详细解释这些标志吗?最好使用在将一个标志翻转到另一个标志时显示不同行为的示例。


我不知道答案,但是请在获得答案时更新wiki.nginx.org。另外,英语nginx邮件列表非常活跃,Igor(主要开发人员)每月都会回答数百个问题,所以也许在那里问。
rmalayter

@rmalayter-在Nginx邮件列表中询问了这个问题。伊戈尔(Igor)回答了这个问题,但答案对我来说也没有太大意义:pubbs.net/nginx/200908/46047

域名被接管后,pubbs.net链接已断开。抱歉,无法找到应该指向的位置。;(
Tino 2012年

Answers:


40

对于不同的位置,您可能具有不同的重写规则集。当重写模块遇到时last,它将停止处理当前集合,并且再次传递重写请求以找到适当的位置(以及新的重写规则集)。如果规则以结束break,则重写也将停止,但是重写的请求不会传递到另一个位置。

也就是说,如果有两个位置:loc1和loc2,并且loc1中有一个重写规则,将loc1更改为loc2并以结束last,则请求将被重写并传递到位置loc2。如果规则以结束break,它将属于位置loc1。


您的意思是,如果重写具有break标志,它将不会搜索匹配的位置块,因此使其属于位置loc1。
Martin Fjordvald 2010年

究竟。固定。
minaev 2010年

43

OP首选一个例子。另外,@ minaev写的只是故事的一部分!所以,我们开始...

示例1:无(中断或最后一个)标志

server {
    server_name example.com;
    root 'path/to/somewhere';

    location / {
        echo 'finally matched location /';
    }

    location /notes {
        echo 'finally matched location /notes';
    }

    location /documents {
        echo 'finally matched location /documents';
    }

    rewrite ^/([^/]+.txt)$ /notes/$1;
    rewrite ^/notes/([^/]+.txt)$ /documents/$1;
}

结果:

# curl example.com/test.txt
finally matched location /documents

说明:

对于rewrite,标志是可选的!

示例2:外部位置块(中断或最后一个)

server {
    server_name example.com;
    root 'path/to/somewhere';

    location / {
        echo 'finally matched location /';
    }

    location /notes {
        echo 'finally matched location /notes';
    }

    location /documents {
        echo 'finally matched location /documents';
    }

    rewrite ^/([^/]+.txt)$ /notes/$1 break; # or last
    rewrite ^/notes/([^/]+.txt)$ /documents/$1; # this is not parsed
}

结果:

# curl example.com/test.txt
finally matched location /notes

说明:

外面的位置块,都breaklast在精确的方式表现...

  • 不再解析重写条件
  • Nginx内部引擎进入下一阶段(搜索location匹配项)

示例3:内部位置信息块-“中断”

server {
    server_name example.com;
    root 'path/to/somewhere';

    location / {
        echo 'finally matched location /';
        rewrite ^/([^/]+.txt)$ /notes/$1 break;
        rewrite ^/notes/([^/]+.txt)$ /documents/$1; # this is not parsed
    }

    location /notes {
        echo 'finally matched location /notes';
    }

    location /documents {
        echo 'finally matched location /documents';
    }
}

结果:

# curl example.com/test.txt
finally matched location /

说明:

在位置块内,breakflag将执行以下操作...

  • 不再解析重写条件
  • Nginx内部引擎继续解析当前location

示例4:内部位置块-“最后一个”

server {
    server_name example.com;
    root 'path/to/somewhere';

    location / {
        echo 'finally matched location /';
        rewrite ^/([^/]+.txt)$ /notes/$1 last;
        rewrite ^/notes/([^/]+.txt)$ /documents/$1;  # this is not parsed
    }

    location /notes {
        echo 'finally matched location /notes';
        rewrite ^/notes/([^/]+.txt)$ /documents/$1;  # this is not parsed, either!
    }

    location /documents {
        echo 'finally matched location /documents';
    }
}

结果:

# curl example.com/test.txt
finally matched location /notes

说明:

在位置块内,lastflag将执行以下操作...

  • 不再解析重写条件
  • Nginx内部引擎开始根据结果​​结果寻找另一个位置匹配项rewrite
  • 不再分析重写条件,即使在下一个位置匹配时也是如此!

摘要:

  • rewrite带有标志breaklast匹配的条件时,Nginx停止解析rewrites
  • 在位置块之外,使用breaklast,Nginx会执行相同的工作(不再处理重写条件)。
  • 在一个位置块中,使用break,Nginx仅停止处理重写条件
  • 在带有的位置块内last,Nginx不再处理重写条件,然后开始寻找与该location块的新匹配!Nginx也会忽略rewriteslocation块中的任何内容!

最后说明:

我错过了包含更多边缘情况(实际上是重写常见的问题,例如500 internal error)。但是,这超出了这个问题的范围。示例1可能也超出范围!


错误:“ nginx.service失败,因为控制进程退出并显示错误代码。” ...未知指令“ echo”
Peter Krauss

nginx.com/resources/wiki/modules/echo。某些Linux发行版(例如Ubuntu 14.04及更高版本)将此模块捆绑在某些软件包中(例如,在nginx-extras中)。希望对您有所帮助。
Pothi Kalimuthu

1
在示例1中,如果将重写规则放在所有三个location指令的上方,会有所不同吗?
Craig Hicks

1
@CraigHicks不,不是。重写规则具有更高的优先级,并且在位置匹配之前首先执行。
Pothi Kalimuthu

1
这应该是最好的答案。通过参考这些示例并阅读nginx文档,很容易理解。
Don Dilanga
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.