资讯专栏INFORMATION COLUMN

Nginx Location匹配规则

Lorry_Lu / 2452人阅读

摘要:先验证第二条普通之间的匹配顺序按最大前缀匹配配置普通普通测试链接,状态码为,符合预期。将正则的规则改下普通普通正则测试链接,状态码,匹配到,并且因为接下来没有符合的正则,所以最终返回为,符合预期。

本文非完全原创, 更多的是将相关资料进行整理

Last-Modified: 2019年5月10日15:28:29

参考链接

linux Nginx配置篇:location的匹配规则(附测试验证过程)

规则语法
语法 匹配规则
普通匹配(遵循最大前缀匹配规则, 优先度比正则低)
= 精确(严格)匹配, 优先度最高
后续不再匹配正则
^~ 非正则匹配(依然遵循最大前缀匹配规则)
后续不再匹配正则
~ 表示区分大小写的正则匹配
~* 表示不区分大小写的正则匹配
/ 通用匹配,任何请求都会匹配到(本质上等同于语法 )

!~!~* 分别为区分大小写不匹配及不区分大小写不匹配 的正则, 但是是用于条件判断的时候(即 if 语句)

if ($host !~* "^www.") {
    # ...
}

匹配简单来说:

优先匹配 = 精确匹配, 若未匹配到则转下一步骤

依照最大前缀匹配规则, 先匹配普通规则( , ^~)

若最终匹配到 ^~, 则使用

若匹配到 或 未匹配到, 则转下一步骤(当前匹配结果暂时保存)

按照物理存储顺序, 若匹配到任意一条正则, 马上使用(无视后面正则)

若未匹配到任意正则, 则使用步骤2中匹配到普通正则

location 分类

只有两类:正则location和普通location

~~* 为正则location
=^~@和无任何前缀的都属于普通location,另外,@是用作服务端内部的一种转发行为,很少用,在此不做讨论。

匹配顺序:

先普通,再正则

普通location之间的匹配顺序:按最大前缀匹配
location /a/{}location /a/b/ {},请求 http://a/b/c.html 匹配的是 location /a/b/ {}

正则location之间的匹配顺序:按配置文件中的物理顺序匹配,只要匹配到一条正则,就不再考虑后面的

若普通location匹配到 精确匹配= 或 非正则匹配 ^~, 则不再进行后续的正则匹配

普通location与正则location之间的匹配结果选择

普通location先匹配,匹配到了结果,只是一个临时结果;

会继续正则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,符合预期。

另附上常用正则表达式:

. : 匹配除换行符外的任意字符

? : 重复0次或1次

: 重复1次或更多次

: 重复0次或更多次

d :匹配数字

^ : 匹配字符串的开始

$ : 匹配字符串的结束

{n} : 重复n次

{n,} : 重复n次或更多次

[c] : 匹配单个字符,如此处的字符 c

[a-z] : 匹配a-z小写字母的任意一个

(a|b|c):匹配a或b或c

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/40429.html

相关文章

  • nginx location配置规则学习

    摘要:然后检查正则表达式,按照它们在配置文件中的显示顺序。正则表达式的搜索在第一个匹配中终止,并且使用相应的配置。正则表达式可以包含稍后可以在其他指令中使用的捕获。 最近学习vuejs,做前后端分离,demo做完了,最终还是要发布的,于是学习nginx,其它配置倒是还好理解,唯独对localtion理解不了,最后请教了一些网友,才得以解决问题,但是不希望下次还遇到问题,所以这里把localt...

    CoffeX 评论0 收藏0
  • 在开发环境下使用nginx重写uri及代理功能

    摘要:本文同步在个人博客上,欢迎关注这篇文章整理了在前端开发中,在开发环境下使用重写及代理功能的方法。表示该规则是使用正则定义的,区分大小写。因此牢记在上下文中使用,而在上下文中使用。 本文同步在个人博客shymean.com上,欢迎关注 这篇文章整理了在前端开发中,在开发环境下使用nginx重写uri及代理功能的方法。 参考 nginx中文文档 前端开发者必备的 Nginx 知识 Ngin...

    LMou 评论0 收藏0
  • Nginx 学习总结(3)—— Location 模块

    摘要:改为后,显示出文件的大概大小,单位是或者或者默认为,显示的文件时间为时间。 这是 Nginx 学习总结的第三篇,上一篇介绍到了 Nginx 学习总结(2) —— 基本配置,这一篇会对Location 模块 做一些总结。我们知道,Location 模块 主要是用于针对某些特定的 URL 进行配置,可以由前缀字符串定义,也可以由正则表达式定义。 Location 匹配规则 location...

    biaoxiaoduan 评论0 收藏0
  • nginx执行请求的工作原理之location匹配详解

    摘要:作为一名,配置是我们必会的技能项之一。只有请求的路径与后面的字符串完全相等时,才会命中。举例表示该规则是使用正则定义的,区分大小写。举例匹配优先级最后,我们了解下的查找规则。 作为一名PHPer,配置nginx是我们必会的技能项之一。但是当用户请求到达nginx之后,是如何匹配到对应的配置项的呢? location语法规则 首先我们先了解下location的语法规则,location语...

    jlanglang 评论0 收藏0
  • Nginx location你需要知道这些!

    摘要:首先,首先会检查所有的前缀,从中选出最长前缀匹配也就是修饰符后面的路径最长的的并记下。然后,如果存在正则时,按照其出现的顺序,依次匹配,找到匹配的正则就不再继续往下,并选择该作为最终的结果。 场景: 在项目开发中经常会遇到nginx配置文件中,会有很多条location配置,却读不懂其中的含义而烦恼 Location是什么? Location是Nginx中的块级指令(block dir...

    Atom 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<