精确位置匹配在 nginx 中如何工作?

how does an exact location match work in nginx?

在下面的代码中,index 指令将 page1.htm 添加到 / 请求。所以我希望 http://DOMAIN 的完全匹配与第二个位置块匹配,而不是第一个。

index page1.htm;

location = /
    {
    rewrite / /page2.htm;
    }

location = /page1.htm
    {
    rewrite /page1.htm /page3.htm;
    }

但这是第一个匹配的位置。 http://DOMAIN 给我 page2.htmhttp://DOMAIN/page1.htm 给我 page3.htm.

=前缀启用什么样的精确匹配?

我浏览了很多文档,但我不清楚这里发生了什么。如果第一个位置被删除然后 http://DOMAIN 给我 page3.htm 所以它似乎在尝试位置匹配之前使用索引。那么在上面的例子中,为什么 location = / 在应用索引后 uri 变成 /page1.htm 时匹配?

是否先在没有应用索引的情况下测试位置,然后只有在没有匹配时,才在应用索引的情况下再次测试它们?

URL http://example.comhttp://example.com/ 对于 HTTP 实际上是完全相同的。两者都将发送为

GET / HTTP/1.1
Host: example.com
... other headers

表示路径部分永远不会为空,并且始终以斜杠开头 /。在那种情况下,很明显,您对 http://example.com 的请求最终以 page2.htm.

结束

步骤:

  1. Nginx 找到完全匹配 / 并将请求重写为 /page2.htm
  2. 没有位置匹配 /page2.htm 所以 nginx 只提供静态文件。

您可以看到 index 从未在此处使用过。

我发布答案以防其他人正在研究这个相当晦涩的问题。进一步的测试揭示了以下内容:

  1. 当 uri 到达服务器块时,它通过 没有应用任何 index 指令的位置。

  2. 如果生成的路径解析为有效目录,并且存在 index 指令,则索引中的文件名按顺序排列 附加到路径并进行测试以查看是否存在有效文件。

  3. 如果第 2 步导致路径更改(通过添加存在的索引文件名),将使用新路径再次解析位置。

nginx documentation 对此非常清楚:

A location can either be defined by a prefix string, or by a regular expression. Regular expressions are specified with the preceding “~*” modifier (for case-insensitive matching), or the “~” modifier (for case-sensitive matching). To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered. Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.

...

Also, using the “=” modifier it is possible to define an exact match of URI and location. If an exact match is found, the search terminates.