nginx之location匹配顺序详解
网上有很多讲解location匹配顺序的,但发现,要么模模糊糊,要么讲解不完全正确。
基本语法
语法 | location [ location |
---|
类型 | 参数 | 匹配规则 | 示例 |
前缀字符串(prefix string) | = | 精准匹配 | =/demo {} |
^~ | 从请求 uri 的开头进行匹配 | ^~ /demo {} | |
空 | 从请求 uri 的开头进行匹配 | /demo{} | |
正则表达式(regular expression) | ~ | 区分大小写的正则匹配 | ~ /demo{} |
*~ | 不区分大小写的正则匹配 | *~ /demo{} |
(注:本文不讨论@name的形式)
匹配顺序
1.先精准匹配 =
,精准匹配成功则会立即停止其他类型匹配,使用该 location的配置;
2.没有精准匹配成功时,进行前缀字符串匹配。包括查找空参数和带有^~ 的前缀匹配。完成所有的前缀匹配后,如果是带有 ^~
的前缀匹配是最长的匹配,则立即结束匹配,使用^~修饰符中最长的前缀匹配的location配置。如果最长的是空修饰符,则将其暂存,继续查找正则匹配(网上很多文章在这里讲解错误了)
3.查找正则匹配 ~
和 ~*
。当同时有多个正则匹配时,按其在配置文件中出现的先后顺序优先匹配,命中则立即停止其他类型匹配;
4.所有正则匹配均未成功时,返回步骤 2 中暂存的普通前缀匹配结果
实践
实验匹配顺序1内容
location /test { default_type text/html; return 200 '/test'; } location ~ /test { default_type text/html; return 200 '~ /test'; } location = /test { default_type text/html; return 200 '= /test'; }
请求lcoalhost/test,返回=/test,符合我们的预期,=
选项的优先级最高
实验匹配顺序2,3,4点内容:
location /te { default_type text/html; return 200 '/te'; } location ^~ /t { default_type text/html; return 200 '^~ /t'; } location ^~ /test { default_type text/html; return 200 '^~ /test'; } location ~ /test { default_type text/html; return 200 '~ /test'; } location /test/more { default_type text/html; return 200 '/test/more'; }
A.如果输入localhost/test,返回^~ /test 符合逾期,查找过程如下:
1.没有=,继续进行其他搜索
2.查找前缀匹配,匹配到了 /te 、^~ /t 、 ^~ /test ,因为^~/test是最长的前缀匹配,所以使用该配置,停止其他搜索
B.如果输入 localhost/test/more,返回 ~ /test ,符合预期,查找过程如下:
1.没有=,继续进行其他搜索
2.查找前缀匹配,匹配到了 /te 、^~ /t 、 ^~ /test、/test/more ,因为/test/more是最长的前缀匹配,它是空修饰符,所以暂存、然后继续进行正则匹配
3.正则匹配,匹配到了 ~/test,命中,立即结束,使用该location下的配置,符合预期