nginx - 重写指令如何与标志一起匹配位置?

Eri*_*ang 0 nginx

应该跟随nginx配置是死循环吗?

location / {
    # url rewrites
    rewrite ^/(.*).jsp$ /$1.html last;

    try_files $uri $uri/ =404;
}

根据doc似乎应该,但在测试中它似乎与以下相同:

rewrite ^/(.*).jsp$ /$1.html break;

@Update

关于last,nginx doc说:

它开始搜索与重写的URL匹配的新位置.

问题是:

  • 那是什么意思?这是否意味着搜索下一个location指令?
  • 如果只有1个location当前last所在的位置,它应该停止还是......?

Iva*_*lev 6

为了解释这一点,我们来看看这个示例配置:

server {
    listen 80;
    server_name localhost;

    location / {                   #  Location #1
        root /some/path;
    }

    location ~ ^/(foo|bar|baz) {   #  Location #2

        rewrite ^/foo /bar;        #  Rewrite rule #1
        rewrite ^/bar /baz break;  #  Rewrite rule #2
        rewrite ^/baz /qux last;   #  Rewrite rule #3
        rewrite ^/qux /foo;        #  Rewrite rule #4

        root /another/path;
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 如果我们尝试http://localhost/foo在浏览器中打开会发生什么:

    Nginx解析请求,获取URI part(/foo),然后查找与此请求的URI匹配的所有位置.在这种情况下,两个位置都匹配URI,但由于Location #2是使用正则表达式定义的,因此Nginx将选择它Location #1,或者换句话说,将使此位置成为请求上下文.您可以在文档中找到有关位置优先级的一些信息 .

    现在确定了位置,Nginx开始逐个执行在其中找到的所有重写指令.

    Rewrite rule #1执行之后,URI从更改为 /foo,/bar并且Nginx继续执行下一个重写指令,即Rewrite rule #2.

    Rewrite rule #2执行URI再次发生变化,此时距离/bar/baz.并且由于使用了break标志,Nginx将不会在此位置执行其余的重写指令.所以这次Rewrite rule #3Rewrite rule #4 不会执行也不会执行.

    结果,/another/path/baz将在浏览器中显示.

    如果我们http://localhost/bar 直接请求,将提供相同的文件.只有在这种情况下Rewrite rule #1才会执行(因为/bar不匹配^/foo).

  2. 现在如果我们尝试打开http://localhost/baz这个过程就会这样:

    所述Location #2将被选择作为上下文,因为它是一个更高的优先级和所述请求相匹配.无论是Rewrite rule #1Rewrite rule #2将被忽略,因为/baz不匹配,要么^/foo^/bar.

    breakRewrite rule #2将随着规则本身被忽视,因为标志会影响只有当通过以该标志属于规则重写的URI的过程.

    Rewrite rule #3场比赛的URI,所以它会被执行.该规则将URI更改/baz/qux,然后整个过程被中断,因为该last标志启动.它的作用基本上是告诉Nginx停止处理请求并从一开始就开始,但这次使用重写的URI.

    所以Nginx再次开始寻找合适的位置,但这次URI /qux不是/baz.并且由于Location #2不匹配/qux,因此Location #1被选为请求上下文./some/path/qux服务也是如此 (注意路径).

    这里最有趣的部分是我们从the的上下文开始Location #2Location #1因为last旗帜而结束.

这一切都是如此.是的,如果只有一个位置,它将再次使用(假设它与重写的URI匹配),但这次使用新的(重写的)URI.是的,有可能导致带有不幸配置的无限循环.虽然Nginx会在10个左右的周期后检测并中断它.

PS如果你想知道Rewrite rule #4,在这种配置中它是一个"死指令".它永远不会被执行.