在前面几篇文章中,为了表述某个问题,我们都会举例说明,其中用的最多的都是以locaiton开头的配置例子,形式基本如下:
location / {
// 一些指令
}
特别是在ngx中的变量中出现的最多,它就是我们这篇文章要介绍的核心内容。
1什么是location
它是nginx基于http协议跟外界沟通的桥梁,用来匹配并执行一个规范化的(normalized)URI,任何http请求都需要经过它的“同意”才能通过nginx的大门。那究竟什么样的请求可以进入这个大门呢?这取决于location 后面配置的是什么样的规则,比如我们常见的一种配置:
location /a {
return 200 “hi $uri”;
}
表示以“/a”开头的请求都可以进入,当你通过curl以“/a”进行访问的时候,你会明确得出一个结果:
curl http://127.0.0.1/a
hi /a
那如果请求是“/a/b”和“/b/a”呢?很显然,第一个可以明确输出
hi /a/b
因为它符合以“/a”开头的规则。第二个因为不符合规则所以就直接返回404了(但如果b 是nginx可感知的文件路径,并且该路径下有一个a文件,那么请求“/b/a”会返回这个文件,这部分内容会在后续文章中提到,目前先按404对待)。
到这里我们会看到,这个location有点像战争题材电视剧中的哨兵,而这个规则就是口令,为了防止敌人潜入部队,巡逻的士兵或站岗的哨兵会和来访人员进行口令对比,如果来访人员答不上来,那麻烦可就大了,具体是哪种麻烦这取决于部队。
回到nginx,它的实际匹配方式并没有像我们之前介绍的那样单一,它可以有多种匹配模式,它们之间并没有优略之分,你可以根据实际场景来选择任何你认为合适的模式对请求进行匹配。
2location的六种匹配模式
在nginx中,每个location块在匹配uri时都可以指定一个修饰符,不同的修饰符对请求的匹配范围是不一样的。 除了上面简单介绍的无修饰符location外,nginx中还有多种location修饰符,总结起来的话可以分为六种,分别是【无】【=】【^~】【~*】【~】【@】,而且每种修饰符都有它特定的匹配方式和特性,具体有哪些不同,我们会在接下来的内容中对其一一解释。
2.1精确匹配
在nginx中有一种匹配模式叫精确匹配(或严格匹配),它只需要在location后面加上 “=”这样的修饰符,像这样:
location = /a {
return 200 “hi $uri”;
}
这种其实更像我们理解中的部队中口令,需要严格匹配。比如部队规定今天的口令是“瞌睡虫”,那么当哨兵喊口令的时候,对方必须说“瞌睡虫”,多一个字不行,少一个字也不行。所以,回到我们这个例子,只有请求是“/a”的时候才会输出唯一正确的值:
curl http://127.0.0.1/a
hi /a
当你多一个字符(如“/a/”),或少一个字符(如“/”)都不会给出正确的输出,这既是精确匹配。
2.2普通匹配
另外一种是我在工作中经常用的无修饰符的location和很少使用的“^~”修饰符的location,我们管它叫“普通匹配”。
关于【无】修饰符的locaiton我们在最开始已经提到过了,现在我们用带“^~”修饰的location来举个例子:
location ^~ /a {
return 200 “hi $uri”;
}
然后用请求“/a”来访问一下:
curl http://127.0.0.1/a
hi /a
看起来和【=】、【无】这两种模式匹配无差啊,再换个请求方式,用“/ab”试试:
curl http://127.0.0.1/ab
hi /ab
到这里可以肯定它跟【=】匹配是不一样的,如果是精确匹配的话会直接返回404的。
我们知道,无修饰符的location是以其后设置的uri作为前缀来匹配请求的,而就目前来看【^~】这种匹配模式也是可以完成【无】模式工作的,所以感觉这种修饰符应该还会另有他用,会不会是后缀匹配呢?用“/b/a”和“/ca”试试看:
curl http://127.0.0.1/b/a
curl http://127.0.0.1/ca
结果这俩货不约而同的都打出了404,显然我们的推测是错误的。
实际上【无】和【^~】修饰符单在匹配uri规则上是完全一样的,都是以其后紧邻的uri作为前缀来匹配请求的。要说清楚这个问题需要把下一小节讲的内容“正则匹配”提前拿过来,因为它们的区别就在对正则匹配的处理上,来看下面这个例子(这两个location在同一个nginx配置中):
location /a {
return 200 “hi $uri”;
}
location ~ /a {
return 200 “Hi I am regex”;
}
在上面的例子中,带“~”修饰符的location是可以正则匹配请求的,我们用请求“/a”来访问一下这个例子看会有什么效果:
curl http://127.0.0.1/a
Hi I am regex
通过结果可以看到,当前请求匹配的是支持正则匹配的那个locaiton,而且,似乎正则模式的匹配比无修饰符模式的匹配优先级要高。
那如果在无修饰符的location加上“^~”会是什么情况呢?来看实际例子(这两个location在同一个nginx配置中):
location ^~ /a {
return 200 “hi $uri”;
}
location ~ /a {
return 200 “Hi I am regex”;
}
此时我们用同样的请求“/a”来发起请求:
curl http://127.0.0.1/a
hi /a
怎么样?是不是有点“拨乱反正”的感觉,当你加上“^~”修饰符后你的location一下子就提高了匹配优先级。
此时有些读者可能会想,是不是因为带“^~”修饰符的location放在了带“~”修饰符location前面的原因?真的是这样吗?那我们把它反过来再看看:
location ~ /a {
return 200 “Hi I am regex”;
}
location ^~ /a {
return 200 “hi $uri”;
}
用同样的uri发起请求:
curl http://127.0.0.1/a
hi /a
可以看到,跟location配置未颠倒之前的打印结果是一样的。
至此我们可以得出一个结论,【无】、【^~】这两种匹配模式在uri的匹配上是完全一致的,都是以其后配置的uri作为前缀来匹配请求的。不同的是当nginx配置文件中同时存在正则匹配时,【无】的匹配优先级要低于正则匹配,而【^~】的匹配优先级要高于正则匹配。
2.3正则匹配
正则匹配,顾名思义,就是支持正则的location,在nginx中可以使用【~】或【~*】来标识,一旦打上这个标识,那么在其后的uri就变成了正则表达式。其中,【~】表示匹配的过程要区分大小写,而【~*】则表示不区分大小写,其它方面两者没有任何区别,所以为了节省篇幅,本节仅用【~】来举例说明。
关于正则匹配的具体使用规则,我们还是老规矩,先看例子:
location ~ /a {
return 200 “hello”;
}
然后直接用“/a”发起一个请求
curl http://127.0.0.1/a
hello
?,跟之前介绍的匹配没区别?别急,再用“/b/a”试试:
curl http://127.0.0.1/b/a
hello
这样看是不是就有区别了?像“/b/a”这样的请求,之所以可以匹配上“/a”,是因为加上了“~”符号的“/a”变成了一个正则表达式,此时任何带“/a”的字符串都可以被这个表达式匹配。
上面这个例子虽然用到了正则匹配,但是并没有用到正则的一些专有符号,所以总是感觉少点什么,现在我们再来举几个例子来把这一点给补上,先看一个简单的,用正则匹配模拟普通匹配
location ~ ^/a {
return 200 “hello”;
}
当前配置中的“^”符号表示匹配字符串的“行首”,也可以简单理解成从行首开始匹配,所以“^/a”的意思就是,匹配以/a开头的字符串。这种规则是不是跟普通匹配模式很像?来,curl验证一下:
curl http://127.0.0.1/b/a -v
< HTTP/1.1 404 Not Found
curl http://127.0.0.1/a/b
hello
可以看到,之前可以正常返回结果的请求“/b/a”此时却返回了404,而请求“/a/b”则因为是以“/a”开头,所以返回了正确的结果。
简单的例子说完了,再来看一个稍微复杂一点的,假设现在有这样一个需求:我们需要某个location只匹配以“数字”开头,结尾是“.html”,且数字的个数最多不能多于5个,最少不能少于1个。对于这样的一个需求,可以用下面的正则匹配来完成:
location ~ “^/\d{1,5}\.html$” {
return 200 “hello”;
}
其中“^”符号在前面已经说过了,用来表示行首。而“\d”符号在正则表达式中表示0到9的任意一个数字,紧接着用“{1,5}”来表示这个数字可以出现1到5次。随后是我们约定的以“.html”结尾,所以需要在最后加一个“行尾”符“$”。最后我们看到在“.html”前还有一个“\”符号,这其实是一个转义符,因为“.”在正则表达式中表示一个任意字符,前面加上转义符“\”后,“.”就只是一个普通的符号了。解释了那么多,用几个请求验证一下:
curl http://127.0.0.1/1234.html
hello
curl http://127.0.0.1/12t34.html
< HTTP/1.1 404 Not Found
curl http://127.0.0.1/.html
< HTTP/1.1 404 Not Found
从输出可以看到,除了第一个返回了正确的结果,其它的请求都因为匹配失败返回404。
在正则中,除了上面提到的“常规”匹配,还有一种叫子匹配(子模式、group等),nginx中对这种子匹配也是支持的,我们来看一个在nginx中使用子匹配的例子:
location ~ ^/(.)(.)(.) {
return 200 “hello -> [$1]-[$2]-[$3]”;
}
其中“.”表示任意单个字符;“()”表示一个子匹配,而“$1”、“$2”、“$3”则表示对应的子匹配中的内容;在这个例子里有三个“()”符号,表示一共有三个子匹配,“$”符号后加数字可以表示对应的子匹配内容。用几个请求来看一下效果:
curl http://127.0.0.1/1234
hello -> [1]-[2]-[3]
curl http://127.0.0.1/abcd
hello -> [a]-[b]-[c]
通过输出结果并对照上面的解释,应该会很容易的明白子匹配在nginx中的使用,另外一点需要注意的是,在nginx中,最多支持9个子匹配,且是前9个,后续的会被忽略。
最后,本节主要讲述了正则表达式在nginx中的使用,关于正则表达式本身的更详细的规则,读者只能自己google了。
2.4内部匹配
除了上面提到的几种匹配模式,nginx中还有一种特殊的匹配,我们可以叫他“内部匹配”,在配置文件中使用【@】表示。这里“内部”的意思是指外部用户看不到的location,目前nginx中只有几个指令能看到这种匹配(比如error_page、try_files等)。
好,我们针对上面这句开场白来做几个例子,看看它究竟是如何玩的,首先看一个正常的配置:
location /a {
return 200 “hello”;
}
这个例子已经看到无数次了,对于“/a”这样的请求一定会打印出“hello”。现在我们把这个例子改成内部匹配模式,像这样:
location @/a {
return 200 “hello”;
}
注意这个“@”符号和后面的“/a”中间没有空格,否则的话nginx无法启动成功,不要问为什么,这是“龟腚”。好,现在再用“/a”请求一下试试:
curl http://127.0.0.1/a -v
< HTTP/1.1 404 Not Found
< Content-Type: text/html
< Content-Length: 175
意料之中,直接404了。有的同学可能会说,是不是你的请求不对,应该用“@/a”请求才对,但是仔细一想,这种请求显然是不成立的,因为它的完整url会是这样:
http://127.0.0.1@/a
是不是很奇怪,这根本就不是一个合法的请求。
外部正常请求的方式失败了,那所谓的内部匹配方式又是怎么玩的呢?本节开始的时候我们说过,目前nginx中只有几种指令可以使用这种匹配,这其中就包括我们常用的“error_page”指令。该指令在nginx的作用是为某些错误响应码指定一个uri,意思是当某个请求的响应发生错误时,它的响应码正好被“error_page”指定,那么它的响应内容将是该指令后对应的uri展示的内容。还是有点绕,直接看例子把:
error_page 404 /a;
location /a {
return 200 “This is a error page”;
}
当前配置中只有一个“/a”location规则,为了演示这个例子,我们需要用这种location匹配不到的请求来访问,比如“/b”,根据以往的经验,如果没有“error_page”指令,这种请求应该会返回404,而加上这个指令后效果是这样的:
curl http://127.0.0.1/b -v
< HTTP/1.1 404 Not Found
< Content-Length: 9
This is a error page
可以看到,响应码还是404,但是响应内容已经变成“/a”location所输出的内容了。
但是现在有一个问题,对于“/a”这样一个配置,只有在其他请求出错的时候才会用到,所以我们显然是不想让用户直接访问的,这个时候【@】这种方式就排上用场了,这个配置可以改成这样:
error_page 404 @/a;
location @/a {
return 200 “This is a error page”;
}
此时再用“/b”试一下
curl http://127.0.0.1/b -v
< HTTP/1.1 404 Not Found
< Content-Length: 9
This is a error page
看结果显然是符合预期的,而原来的“/a”在配置中已经不存在。
实际上对于【@】这种匹配方式,在nginx中是完全独立存在的,其它模式都是从NGX_HTTP_FIND_CONFIG_PHASE阶段(后续有文章专门介绍,这里知道有这么一个东西就行,不必深究)开始匹配location的,而【@】则超三界之外,不在五行之中,直接走自己独立的匹配道路。它的内部实现逻辑大致是这样:当nginx的所有location被加载完毕后,所有带“@”的location会被单独放到一个容器中,任何支持这种location的指令,在使用的时候都是去这个容器中做完全匹配的。而且这种匹配并没有uri的概念,也就是说,我们在使用的时候并不需要把它伪装成uri,像这样就可以:
error_page 404 @a;
location @a {
return 200 “This is a error page”;
}
同时它也没有什么特殊的匹配规则(比如以某个字符串前缀来匹配),从字符匹配上来说,跟精确匹配很像,多一个字符不行,少一个字符也不行,必须严格匹配。
另外一种跟【@】这种内部匹配规则很像的是带有internal指令的location,不同的是【@】只能被极少数指令使用,而带internal指令的location则适用与所有的内部请求,它不会更改原location的匹配流程(比如【@】方式会绕过NGX_HTTP_FIND_CONFIG_PHASE阶段,直接从单独容器中匹配),只会更改当前location的访问权限。
那什么是内部请求?大部分内部请求都符合这么一个特点:外部请求进入nginx后,都或多或少被nginx“倒过手”。比如rewrite指令,对于一个有着internal的location,外部请求是不能直接访问的,但是被rewrite重写uri后就可以,比如下面这个例子:
location /a {
internal;
return 200 “hello”;
}
location /b {
rewrite / /a;
}
当我们用curl访问“/a”请求时会直接返回404,而用“/b”请求则可以打印出正确的结果“hello”,原因是因为rewrite指令更改了当前请求的内外性质,把它变成了一个内部请求。
内部请求的实现原理大致是这样:nginx在配置阶段会把包含internal指令的location都打上一个内部标识(比如internal=1),然后,当某个请求成功匹配到该location后,nginx会先检查当前请求是否也被打上了内部标识(比如r->internal=1),如果没有,则拒绝请求,反之则通过。而上面提到的rewrite就是这种可以为当前请求打上内部标识的指令,另外像error_page、try_files、index等指令都可以,还有像add_before_body这种用子请求的方式实现功能的指令也是可以的。(关于子请求,后续会有专门文章进行详细介绍)
2.5后缀是“/”的location
在nginx中还存在这样一种不太容易被发现的规则,当某个location的后缀是“/”时,该locaiton可以成功匹配一个后缀不是“/”符号的请求。
上面这句话读起来好像有点绕,没关系,来看一个实际的例子:
location /a/ {
proxy_pass https://www.baidu.com/;
}
从前面学到的知识我们可以知道,上面这个location匹配的uri是以“/a/”开头的请求,而我们最上面那句话“该locaiton可以匹配上一个后缀不是“/”符号的请求”又扩大了这个location的匹配范围,意思是它也可以匹配“/a”这个请求,因为“/a”比配置中的location正好在结尾处少一个“/”。在验证这条规则之前我们先用正常的请求来访问一下看看结果:
curl http://127.0.0.1/a/ -v
< HTTP/1.1 200 OK
< Content-Type: text/html
< Content-Length: 2443
从响应头可以看出他返回了正确的内容,并且内容长度为2443个字节。好,接下来再用“/a”请求一下试试:
curl http://127.0.0.1/a -v
< HTTP/1.1 301 Moved Permanently
< Content-Type: text/html
< Content-Length: 190
< Location: http://127.0.0.1/a/
可以看到,并没有返回404,而是一个301,并且有一个Location响应头。仔细看这个响应头的内容,比我们原请求多了一个“/”符号。去掉scheme和
host部分,单看uri它正好是“/a/”跟我们例子中location配置的uri是一致的,有点类似于nginx自动修正了这个请求,把他导向了一个正确的匹配。
针对这条“/”后缀的规则,我们可能会产生另外一种疑问,如果没有“/”后缀的和有“/”这个后缀的location同时存在,那nginx会选择哪个来匹配?就近?随机?不猜了,举几个例子试一下:
location /a {
proxy_pass https://www.jd.com/;
}
location /a/ {
proxy_pass https://www.baidu.com/;
}
使用curl模拟“/a”请求,多请求几遍,最后出来的结果总是www.jd.com返回的结果,而用“/a/”请求最终出来的结果总是www.baidu.com返回的结果,即使我们把上面两个配置项上下颠倒,结果总是不变的。所以结论是只有类似“/a”这种配置不存在时,与之对应的“/a/”这种location配置在面对“/a”请求时才会表现出自动修正的动作。
另外,细心的读者可能会注意到,之前举例时locaiton里面都是“return”指令,而本节切用的“proxy_pass”指令,难道换个指令会有什么不同?还是用实际例子来看把:
location /a/ {
return 200 “hello”;
}
同样的location,不一样的内部指令,先用“/a/”请求访问以下看看结果
curl http://127.0.0.1/a/
hello
看起来没啥问题,至少证明配置本身没有问题。再用“/a”试试,根据上面的经验,此时应该返回一个301响应码,并且有一个Location头,且内容是“http://127.0.0.1/a/”,究竟是不是呢?来看结果
curl http://127.0.0.1/a -v
< HTTP/1.1 404 Not Found
< Content-Type: text/html
< Content-Length: 175
意思很明显了,代表当前nginx没有一个可以匹配“/a”的location,所以,看到这个结果是不是很困惑?此时你可能会想,之前说的关于有“/”后缀的location规则到底还算不算数?
当然算数,只不过要加上一些限制了。在nginx中并不是所有的指令都支持location这种规则,目前在nginx-1.9.4中只有五个指令(最新版又加了一个grpc_pass),分别是proxy_pass,fastcgi_pass,uwsgi_pass,scgi_pass,memcached_pass。 实际上nginx中所有的location都有这种能力,只不过这种能力默认都是关闭的,如果有需要你可以随时把它打开,不过目前不可以通过配置文件的方式打开,只能通过硬编码的方式,而上面这五个指令之所有能支持这种能力,就是因为它们知道这种硬编码规则,并将其打开了。
到这里关于“/”后缀的规则基本已经结束了,但是通过前面的讲述我们知道,location的匹配有六种规则,目前我们所有的例子用的都是【无】,那么再刨去一个内部匹配【@】,其它四中是否适用这种“/”后缀规则呢?老规矩,直接上例子:
location = /a/ {
proxy_pass https://www.baidu.com/;
}
location ^~ /b/ {
proxy_pass https://www.baidu.com/;
}
location ~* /c/ {
proxy_pass https://www.baidu.com;
}
location ~ /d/ {
proxy_pass https://www.baidu.com;
}
然后我们分别用“/a”,“/b”,“/c”,“/d”来发起请求,看看会有什么结果:
curl http://127.0.0.1/a -v
< HTTP/1.1 301 Moved Permanently
< Location: http://127.0.0.1/a/
curl http://127.0.0.1/b -v
< HTTP/1.1 301 Moved Permanently
< Location: http://127.0.0.1/a/
curl http://127.0.0.1/c -v
< HTTP/1.1 404 Not Found
curl http://127.0.0.1/d -v
< HTTP/1.1 404 Not Found
结果一目了然,【~】、【~*】这两种正则模式不支持这种“/”后缀规则,所以最后这种“/”后缀规则的适用范围还要刨除【~】、【~*】这两种模式匹配。
3匹配模式的优先级
截止到目前,我们已经介绍完了所有六种匹配模式,如果每次只是使用其中的一种,那么对于看过上面内容的同学来说应该不是什么难事,但如果多种模式一起使用呢?比如某个请求正好处在多个模式的交集匹配范围内,此时应该以哪个模式优先呢?或者另外一个古怪的问题,这几个模式是否可以同时存在呢?
针对上面的问题,我们在nginx.conf文件中增加如下配置:
1: location = /a {
return 200 “[= /a]”;
}
2: location /a {
return 200 “[/a]”;
}
3: location ^~ /a {
return 200 “[^~ /a]”;
}
4: location ~ /a {
return 200 “[~ /a]”;
}
5: location ~* /a {
return 200 “[~* /a]”;
}
为了便于解释,每个location前都加了一个数字编号,另外因为【@】匹配模式是一个内部匹配,所以直接排除掉了他,这样一个配置文件中就有五中匹配模式了。
好了,有了上面的这个配置,第一步自然是先启动或是加载nginx,如果你是第一次启动nginx,那么你需要先启动它,我本机安装目录是/my/nginx,所以当进入到安装目录后,我需要做如下操作:
$ ./sbin/nginx
然后敲回车就可以。如果nginx已经是启动状态,那么直接reload就可以,操作如下:
$ ./sbin/nginx -s reload
同样回车就可以了。不管是哪种命令,没有消息就是最好的消息,代表启动或reload成功。因为我本机nginx已经启动,所以我直接reload就可以了,来看一下结果:
$ ./sbin/nginx -s reload
nginx:[emerg] duplicate location "/a" in /my/nginx/conf/nginx.conf:34
遗憾的是居然加载失败(reload)失败,提示信息说有重复的location,因为我们所有的location的uri部分都是“/a”,所以初步怀疑是nginx中不能同时存在同样的location。但是再仔细看这条提示信息,它打印出了错的行数为34,而在我的nginx.conf配置文件中,第34行正好是我们为其编号的第3号location,它的匹配模式是【^~】,所以如果真的是nginx中不能同时存在同样的location,那么是不是在第2号的时候就应该出错呢?有点一头雾水,先把3号location改成下面这样:
3: location ^~ /ab {
return 200 “^~ /a”;
}
然后再reload一次试试:
$ ./sbin/nginx -s reload
回车后发现可以成功reload,难道【^~】模式无法跟其它模式共存吗?当然不是,这其实是因为【^~】模式跟【无】发生了冲突,因为它俩本来就是同一个东西,只不过匹配完成后,后续的动作不一样了。试想一下,在同一个nginx.conf中有两个同样的location,但是其内部指令且不同,那么当有请求过来的时候,nginx应该如何抉择呢?是按照其在配置文件中的顺序匹配?还是随机匹配呢?还是说在【^~】和【无】中定一个优先级呢?nginx给的答案是,不会有这种存在,在配置阶段就将其视为一种错误存在,这条规则同样适用于【=】匹配,但是并不适用于正则匹配。
既然这样,我们就先把3号location放一放,先来看看其它四个location的优先级。先用curl来试一试实际结果:
curl http://127.0.0.1/a
[= /a]
curl http://127.0.0.1/aa
[~ /a]
第一个请求打印出了“[= /a]”应该不会有什么疑问,同样的uri,精确匹配的优先级最高也很合乎常理。而二个请求直接绕过了2号location,并打印出了4号location的结果,这个结果跟我们在2.2节介绍普通匹配时下的结论是吻合的。
所以目前的结论大致是这样:
1.【=】
2.【^~】
3.【~】【~*】
4.【无】
这里面需要注意的是,对于同样的uri,【^~】和【无】只能存在一个,且跟【=】一样,不能重复。但是我们看到,两个正则匹配居然可以重复存在同样的uri,那它们的优先级又是怎样的呢?我们把例子中的4号和5号location的位置互换一下,然后再用同样的请求来试一下结果:
curl http://127.0.0.1/a
[= /a]
curl http://127.0.0.1/aa
[~* /a]
可以看到,第二个请求的输出结果跟之前不一样了,这次是打印出了5号location的结果,所以我们基本可以得出一个结论,正则匹配模式的优先级取决于其在配置文件中的先后顺序。
最后,对于这几种模式的优先级,nginx又是如何实现的呢?
实际上实现方式也很简单,当nginx最终启动成功后,会有三个容器来存放不同的location,其中:
-
【=】【无】【^~】在同一个容器(用S表示)中,并且在容器中按字符升序排 序,如果顺序一样则短的在前,比如uri“/abcd”,一定排在uri“/abc”后面。
-
【~】【~*】两个正则模式在同一个容器(用R表示)中,不过他们并没有按字符升序或长短来排序,同配置文件中的顺序一致。
-
【@】单独在一个容器中。
除了【@】,当有请求过来的时候,大致规则如下:
-
nginx先从S容器中按顺序找匹配,如果匹配到一个【=】则终止后续匹配,否则继续。
-
如果在S容器中匹配到多个【^~】,则以最后一个为准,并返回匹配成功。
-
如果在S容器中匹配到多个【无】,则以最后一个为准,此时会记下这个匹配(记做L1),然后继续从R容器中找匹配。
-
如果在R容器中没有找到合适的正则匹配,则终止后续匹配并以L1作为最终匹配。
-
如果在R容器中找到一个合适的正则匹配,则终止后续匹配,并以当前匹配作为最终匹配。
相关推荐
**Nginx中的Location匹配规则详解** 在Nginx服务器配置中,`location`指令是核心部分之一,用于处理HTTP请求。它根据指定的规则来匹配URL,从而决定如何处理客户端的请求。本文将深入探讨Nginx `location`的匹配...
### Location匹配规则 - **完全匹配**: 使用`=`,优先级最高。 - **前缀匹配**: 没有`=`,按URI长度排序,最长的匹配优先。 - **正则表达式匹配**: 使用`~`或`~*`,按照配置顺序进行尝试,一旦匹配成功,则停止后续...
学习location匹配规则对于理解如何在Nginx中配置服务器和优化网站性能至关重要。 location指令有多种匹配方式,具体包括精确匹配(=)、正则表达式匹配(~和~*)、最前缀匹配(^~)以及前缀匹配。它们都遵循特定的...
本篇文章将深入探讨`location`配置的匹配顺序及其在实际应用中的作用。 ### 1. `location`的基础语法 `location`指令的语法如下: - `location = /pattern { ... }`: 精确匹配。如果请求的URI与指定的模式完全...
- **普通 location** 的匹配规则遵循“最大前缀匹配”原则,即优先选择与请求 URI 最大程度匹配的 location 块。 - **正则 location** 的匹配规则是按照配置文件中的先后顺序来进行匹配的,一旦某个正则表达式匹配...
在本文中,我们将深入探讨Nginx服务器配置中的核心组件之一——`location`匹配规则。`location`指令在Nginx配置中起着至关重要的作用,因为它决定了如何根据请求的URL路由请求。让我们逐步了解其工作原理和配置实例...
- `^~`表示当uri被标准location匹配后,不再使用正则表达式进行匹配。 如果一个请求的uri与多个location块匹配,Nginx会根据上述规则计算出匹配程度最高的location块。如果所有location都未匹配,那么Nginx会根据...
本文将深入探讨`location`的匹配策略及其优先级。 首先,`location`指令分为三种基本类型: 1. **精准匹配 (`location = expression`)**:当请求的URI与`expression`完全相同时,匹配成功。这是最高优先级的匹配,...
本篇文章将深入探讨`Location`指令的正则匹配功能,以及如何利用Nginx进行应用层负载均衡,从而实现高效、灵活的Web服务管理。 首先,我们要理解`Location`指令的基本用法。`Location`可以配合精确匹配、前缀匹配和...
因此,了解`location`的匹配规则至关重要。 **2. `location`匹配规则** `location`的匹配规则主要基于以下几种类型: - **精确匹配 (`=`)**: 使用`=`开头表示精确匹配,只有URI与表达式完全一致时才会匹配成功。 ...
4. **匹配顺序与配置顺序无关**:Nginx在处理请求时,并不按照配置文件中的顺序来决定`location`的优先级,而是根据上面提到的匹配规则来确定。 5. **总结**:理解`location`的优先级对于优化Nginx配置至关重要,它...
总结来说,Nginx处理请求时的匹配规则主要涉及`server_name`和`location`两个层面,通过精确匹配、通配符匹配和正则表达式匹配来确定请求应由哪个`server`和`location`处理。理解这些规则对于优化Nginx配置和提高...
在本文中,我们将深入探讨`location`配置的基本要点,包括它的匹配规则、组织方式以及源码实现。 首先,`location`指令在Nginx配置文件中的作用域分为`main`、`server`和`location`三级。`main`级别的配置适用于...
在服务器配置中,"location"指令是Nginx服务器配置中的关键部分,它用于定义URL匹配规则并指定如何处理这些URL。 1. **Nginx中的`location`指令**: Nginx服务器使用`location`指令来匹配请求的URI,并执行相应的...
在Nginx服务器配置中,`location`指令用于定义URL匹配规则,并决定如何处理客户端的请求。本篇文章将深入探讨如何使用多个`...同时,了解`location`的匹配规则和优先级,对于优化Nginx配置和提升服务器性能至关重要。
在本文中,我们将深入探讨`location`指令的匹配机制以及在多个`if`语句中使用`proxy_pass`的方法。 首先,了解`location`的匹配指令: 1. `~`:表示执行一个正则匹配,区分大小写。 2. `~*`:表示执行一个正则匹配...
Location是Nginx配置文件中用于定义URL匹配规则的关键部分,它可以基于请求的URI来确定请求应该由哪个内部服务器处理。Location指令支持正则表达式匹配,这使得它非常灵活,可以处理复杂的路由需求。 1. **中间件...