前言:nginx的location匹配顺序对于新手来说,上手不太容易,需要一个好的教程,查看了好多的博客,下面总结一下,给大家一个好点的教程吧。
一、先说一下locatin表达式的类型
= 表示普通字符精确匹配。也就是完全匹配。
^~ 表示普通字符匹配。使用前缀匹配,如果匹配成功,则不再匹配其他location。
~ 表示执行一个正则匹配,区分大小写。
~* 表示执行一个正则匹配,不区分大小写。
@ 它定义一个命名的location,使用在内部定向时,例如 error_page,try_files。
以上这几个符号,要记住,下面的匹配规则,都是基于以上几个符号的。
二、详细的讲一下以上的符号
1.全部的location,分为普通location和正则location。
“~”和“~*”前缀的表示正则location(“~”区分大小写,“~*”不分区大小写)
剩下的(“=”,“^~”,“@”)和无任何前缀的都属于普通location。
2.普通location与正则location之间的匹配,选择出普通location的最大前缀匹配结果后,还需要继续搜索正则location。如果继续搜索的正则location也有匹配上,那么正则location将覆盖掉普通location的最大前缀匹配
3.普通location之间:最大前缀匹配
4.正则与正则:按照正则location在配置文件中的顺序匹配的,并且只要匹配到一条正则location,就不在考虑后面的。
5.匹配到普通location后,不在需要继续匹配正则location:只要在普通location前面加上“^~”符号或者“=”严格精确匹配结果(^表示非,~表示正则,字符意思是:不要继续匹配正则)。
“^~”和“=”共同点都可以阻止继续匹配,不同点是“^~”依然遵守“最大前缀”匹配规则,而“=”不是“最大前缀”,是必须严格匹配。
三、下面讲几个例子
1.
location = / { index index.html; [conf A] } location / { [conf B] }
输入http://127.0.0.1/ 会执行到哪里呢?
会执行到conf B,怎么精确匹配的优先级不灵了呢?
事实上,精确匹配还是起作用了,请求目录(非具体文件),nginx会将请求内部定向到index文件,即此时真正的请求是http://127.0.0.1/index.html,这时conf B被命中。
所以精确匹配不要用/来匹配。
2.
location /documents/ { #匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索 #只有后面的正则表达式没有匹配到时,这一条才会采用 [conf A] } location /documents/index.html { [conf B] } location ~ /documents/ {
[conf C] }
输入127.0.0.1/documents/index.html会匹配哪个呢?
会匹配到conf C,因为这个url匹配conf A,也匹配conf B,由于conf B的长度比conf A的长度长,所以conf B被记忆下来,但是后面的正则表达式也匹配,所以就会将前面覆盖掉。
3.
location /documents/ { #匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索 #只有后面的正则表达式没有匹配到时,这一条才会采用 [conf A] } location ~ /documents/ { [conf B] } location ~ /documents/index.html { [conf C] }
输入127.0.0.1/documents/index.html会匹配哪个呢?
会匹配到conf B,首先conf A是匹配的,但是由于是普通location,所以被记忆下来,后面是正则匹配,conf B正好符合,所以就将前面的覆盖掉,终止然后返回了,不在继续向下执行。
4.
location /documents/ { [conf A] } location ^~ /documents/index.html { [conf B] } location ~ /documents/ { [conf C] }
输入127.0.0.1/documents/index.html会匹配哪个呢?
这个会匹配conf B,前两个都是普通匹配,但是由于conf B是“^~”,正好它也是最长前缀,所以将不会在匹配正则location,最终匹配到conf B。