Nginx Location 规则解析:深入剖析 Location 优先级匹配机制

发布时间:2024年01月15日

Nginx Location是什么?

Nginx接受到的请求后,请求发送到什么地方是有Nginx locaiton来定义的。

Nginx Location 规则

语法如下:

location optional_modifier location_match {
    . . .
}
类型功能修饰符示例
前缀字符串None
=
^~
location /prefix
location = /exactmatch
location ^~ /longestmatchnotcheckreg
正则表达式~
~*
location ~ /regularsensitive
locaiton ~* /regularinsensitive

Location匹配优先级(官方文档)

以下是nginx文档中location的匹配过程,英文加上翻译。

步骤English中文
1Test the URI against all prefix strings.将 URI 与所有前缀字符串进行匹配。
2The = (equals sign) modifier defines an exact match of the URI and a prefix string. If the exact match is found, the search stops."=(等号) 修饰符用于精确匹配 URI 和前缀字符串。如果找到精确匹配,搜索停止。
3If the ^~ (caret-tilde) modifier prepends the longest matching prefix string, the regular expressions are not checked.如果 “^~(插入波浪号)” 修饰符前置于最长匹配的前缀字符串,将不会检查正则表达式。
4Store the longest matching prefix string.存储最长匹配的前缀字符串。
5Test the URI against regular expressions.将 URI 与正则表达式进行匹配。
6Stop processing when the first matching regular expression is found and use the corresponding location.当找到第一个匹配的正则表达式时停止处理,并使用相应的位置。
7If no regular expression matches, use the location corresponding to the stored prefix string.如果没有匹配的正则表达式,使用与存储的前缀字符串相对应的位置。

Location 匹配优先级(通俗讲解)

文档中写的比较简洁,理解起来可能有些问题。下面是我总结的比较通俗的讲解:

  1. 先匹配前缀表达式,后匹配正则表达式。
  2. 前缀表达式如果匹配到严格匹配 location = /exactmatch, 则直接结束;
  3. 前缀表达式命中多条,则选择最长的, 如果最长的有正则中止修饰符 location ^~ /longestmatchnotcheckreg , 则结束;
  4. 顺序匹配正则表达式,一但匹配,则结束;
  5. 上面的正则表达式没有匹配到,则使用前面第三步最长的那条前缀规则,并结束;
  6. 什么也没有,就只好使用默认的;
类型功能修饰符示例匹配规则
前缀字符串None
=
^~
location /prefix
location = /exactmatch
location ^~ /longestmatchnotcheckreg
匹配到则直接命中
匹配到且为最长前缀则命中
匹配到且最长,然后没有正则命中 ,该规则才命中
正则表达式~
~*
location ~ /regularsensitive
locaiton ~* /regularinsensitive
匹配到的第一个

注意点

大小写敏感~ 和大小写不敏感 ~*可能在一些系统上并不能正常工作,比如windows,debian对下面的匹配是不同的。/Abc 在windows上匹配到的是 /abc, 而debian 则匹配到的是 /Abc。 说明windows在这里对大小写的处理不是太敏感。
如果需要让windows也区分大小写,可以将第一个的规则修改为 location ~ (?-i)/abc 其中这里使用了regex modifiers (?-i)来关闭大小写不敏感。

location ~ /abc{
    return 200 /abc;
}
location ~* /Abc{
     return 200 /Abc;
}

示例

location  /a{
    return 200 prefix:a;
}
location =  /abc {
    return 200 prefix:exact;
}
location ^~ /abcd {	
    return 200 prefix:ab:withRegStop;
}
location  /abcde{	
    return 200 prefix:abcde;
}
location ~ /ab {
    return 200 regular:ab;
}
location ~ /abcd {
    return 200 regular:abcd;
}

curl 请求结果

# 匹配到前缀 /a, 仅匹配到一个,则为最终结果
$curl -sS pma.test/a
prefix:a

# 匹配到最长前缀 /a,不是完全匹配,也没有正则中止符,因此继续正则匹配,匹配到 ~ /ab
$curl -sS pma.test/ab  
regular:ab

# 匹配到前缀 /a, = /abc, 因为/abc完全匹配,因此最终为 = /abc
$ curl -sS pma.test/abc
prefix:exact

# 匹配到前缀 /a, ^~ /abcd, 没有完全匹配,最长匹配为 /abcd, 同时又正则终止符,因此最终结果为 ^~ /abcd
$ curl -sS pma.test/abcd
prefix:ab:withRegStop

# 匹配到前缀 /a, ^~ /agcd, /abcde, 没有完全匹配,因此最长前缀匹配是 /abcde, 但是没有正则终止符,则继续正则匹配,匹配到的第一个正则为 ~ /ab, 因此最终结果为 ~ /ab
$ curl -sS pma.test/abcde
regular:ab

# 与上面一样
$ curl -sS pma.test/abcdef
regular:ab

参考:

  1. nginx locaiton doc
  2. regex modifiers
文章来源:https://blog.csdn.net/xy707707/article/details/135605980
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。