nginx 重写应该是一个循环

nginx 重写应该是一个循环

chatGPT 是在胡说八道吗,还是我忽略了一些显而易见的东西?

这是我的问题:

我有一个像这样的 nginx 位置块:

    location / {
      location ~ \.html {
        # First send it back to the start with a changed format
        rewrite /(.*) /html/$1  break;
        # Then proxy that to the S3
        proxy_pass https://MYS3.s3.eu-west-1.amazonaws.com;
      }
    }

它应该匹配以 .html 结尾的位置并重写它们以使 request_uri 以 /html/ 为前缀 - 然后将该请求代理到 s3 存储桶。

这有效,但我不明白为什么。为什么重写的带有前缀 /html/ 的 URL 不会通过相同的指令在循环中一次又一次地重写?

ChatGPT 对此作出了回答:

nginx 中的重写指令在位置块内按照特定顺序进行处理。

执行重写时,会从位置块的开头再次处理修改后的 URL。但是,每个请求仅经过一次位置块。

在您的示例中,第一个重写指令重写了请求 URI,将 /html/ 添加到原始 URI 的前面。然后,将新修改的 URI 再次与 location 块进行匹配。但是,这次它与 location ~ .html 指令不匹配,因为修改后的 URI 现在以 /html/ 开头。

因此,执行流程向前移动到 proxy_pass 指令,并且请求被代理到指定的 S3 存储桶,而不会进入重写的无限循环。

总之,重写的 URL 不会进一步重写,因为它与同一位置上下文内的不同位置块匹配。

我只是不明白为什么重写指令不会每次都发生,因为新的 URI 中仍然有“.html”?chatGPT 让我困惑的是

新修改的 URI 再次与位置块匹配...这次它与 location~.html 指令不匹配

不能既匹配又不匹配吗?

这里有谁能为我指明方向:-)

答案1

break你的指令中有标志rewrite文档说它作为休息指示:

停止处理当前的ngx_http_rewrite_module指令集。

如果在地点,请求的进一步处理将继续此位置

假设请求 URL 为/some/file.html。因此,nginx 首先将其重写为/html/some/file.html,然后像存在break指令一样运行。这意味着 nginx 停止执行任何ngx_http_rewrite_module指令(尽管您的例子中没有任何指令)并处理请求当前位置,这意味着它会使用proxy_pass而不会尝试寻找新的location(这是 ChatGPT 错误的部分)。

相关内容