本文非彻底原创, 更多的是将相关资料进行整理html
Last-Modified: 2019年5月10日15:28:29linux
语法 | 匹配规则 |
---|---|
空 | 普通匹配(遵循最大前缀匹配规则, 优先度比正则低) |
= | 精确(严格)匹配, 优先度最高 后续再也不匹配正则 |
^~ | 非正则匹配(依然遵循最大前缀匹配规则) 后续再也不匹配正则 |
~ | 表示区分大小写的正则匹配 |
~* | 表示不区分大小写的正则匹配 |
/ | 通用匹配,任何请求都会匹配到(本质上等同于语法 空 ) |
!~
和 !~*
分别为区分大小写不匹配及不区分大小写不匹配 的正则, 可是是用于条件判断的时候(即 if
语句)nginx
if ($host !~* "^www\.") { # ... }
匹配简单来讲:正则表达式
=
精确匹配, 若未匹配到则转下一步骤空
, ^~
)若最终匹配到 ^~
, 则使用浏览器
若匹配到 空
或 未匹配到, 则转下一步骤(当前匹配结果暂时保存)测试
若未匹配到任意正则, 则使用步骤2中匹配到普通正则url
只有两类:正则location和普通locationspa
~
和 ~*
为正则location=
、^~
、@
和无任何前缀的都属于普通location,另外,@
是用做服务端内部的一种转发行为,不多用,在此不作讨论。.net
location /a/{}
,location /a/b/ {}
,请求 http://a/b/c.html 匹配的是 location /a/b/ {}
=
或 非正则匹配 ^~
, 则再也不进行后续的正则匹配普通location与正则location之间的匹配结果选择code
会继续正则location的匹配,
综上,常规的顺序是匹配完普通location,还要继续匹配正则location,可是,也能够告诉nginx,匹配到了普通location,就不要再搜索匹配正则location了,经过在普通location前面加上^~
符号,^
表示非,~
表示正则,^~
就是表示不要继续匹配正则。
除了^~
,=
也可阻止nginx继续匹配正则,区别在于^~
依然遵循最大前缀匹配规则,而=是严格匹配
location / {}
和 location =/ {}
的区别/ {}
做为普通匹配,是遵循最大前缀匹配原则的,因此,对于一个url,若是有更特殊合适的匹配,就选特殊合适的,若是没有更特殊合适的匹配,也有 / {}
兜着,就像是默认配置同样
=/ {}
遵循的是严格匹配规则,只能匹配到 http://ip:port/,同时会中止搜索正则匹配。
接下来测试验证。
1.先验证第二条:普通location之间的匹配顺序:按最大前缀匹配
nginx.conf配置:
#普通location location /a/b { return 666; } #普通location location /a/b/c { return 777; }
测试连接:http://192.168.88.38/a/b,http状态码为666,符合预期。如图(后面的测试可自行F12打开浏览器控制台查看http状态码,再也不截图):
测试连接:http://192.168.88.38/a/b/c,http状态码为777,匹配的是location /a/b/c {return 777;},符合预期。
2.验证第三条:正则location之间的匹配顺序:按配置文件中的物理顺序匹配,只要匹配到一条正则,就再也不考虑后面的
nginx.conf配置:
location ~* /a { return 999; } #匹配a-z的任意一个字母 location ~* ^/[a-z]$ { return 666; }
测试连接:http://192.168.88.38/a,http状态码999,匹配的是location ~* /a {renturn 999;},符合预期。
将nginx.conf中的两个正则匹配顺序调换下:
location ~* ^/[a-z]$ { return 666; } location ~* /a { return 999; }
测试连接:http://192.168.88.38/a,http状态码666,匹配的是location ~* ^/[a-z]$,符合预期。
3.验证第4条,其实第4条就至关因而总结性的匹配顺序了:
nginx.conf配置:
#普通location location /a { return 666; } #普通location location /a/b { return 777; } #正则location location ~* /a/b { return 888; }
测试连接:http://192.168.88.38/a,http状态码666,匹配到普通location,location /a {return 666;},符合预期。
测试连接:http://192.168.88.38/a/b,http状态码777,先进行普通location匹配,遵循最大前缀原则,匹配到location /a/b {return 777; },可是,这只是一个临时结果,由于接下来还要继续往下进行正则location匹配,匹配到 location ~* /a/b { return 888; },最终返回结果为888。符合预期。
将正则location的规则改下:
#普通location location /a { return 666; } #普通location location /a/b { return 777; } #正则location location ~* /a/c { return 888; }
测试连接:http://192.168.88.38/a/b,http状态码777,匹配到location /a/b {return 777; },而且由于接下来没有符合的正则location,因此最终返回为777,符合预期。
综上,location的匹配顺序及结果取值都符合2,3,4点结论。
接下来再测试验证普通location中的^~及=符号对于匹配搜索过程的阻断效果,固然,别忘了这俩符号的真实做用。^~为普通字符匹配,=为精确匹配。
^~测试验证nginx.conf配置:
location /a { return 666; } #普通匹配 location ^~ /a/b { return 777; } #正则location location ~* /a/b { return 888; }
测试连接:http://192.168.88.38/a/b,匹配到 location ^~ /a/b {return 777;}后,由于使用了^~符号,再也不继续搜索正则location匹配,因此,虽然下面有符合条件的正则location,可是最终仍是返回了777,符合预期。
=测试验证nginx.conf配置:
location /a { return 666; } #普通匹配 location = /a/b { return 777; } #正则location location ~* /a/b { return 888; }
测试连接:http://192.168.88.38/a/b,匹配到 location = /a/b {return 777;}后,由于使用了=符号,再也不继续搜索正则location匹配,最终返回777,符合预期。
另附上经常使用正则表达式: