阅读官方文档后,对nginx中location匹配规则的总结:
http://nginx.org/en/docs/http/ngx_http_core_module.html#location
匹配方式两种:
- 前缀匹配:就是从前面匹配,要求前面是一样的
- 正则匹配:就是匹配正则表达式
两种特殊的前缀匹配:
- = 表明是精确匹配,停止任何后面的匹配
- ^~ 若最长前缀匹配含有前面这个字符,则终止后面的正则匹配
一般的匹配过程:
- 先进行前缀匹配,再进行正则匹配
- 在每种匹配类型的内部,又是按照书写的顺序匹配
- 在前缀匹配中,寻找并记录最长前缀匹配(两个location,
/abc
和/abc/def
那么带uri/abc/def/a.jpg
的请求匹配的最长前缀就是/abc/def
) - 在正则匹配中,
~
和~*
区分大小写和不区分大小写。匹配到就终止后面的正则匹配,并舍弃之前最长前缀匹配。若是正则部分没有匹配到,那么就选择之前的最长前缀匹配。
其他说明:
- 在匹配过程中要注意两种特殊的前缀匹配,所以上面说的是一般的匹配过程
- 当访问
http://localhost
时和访问http://localhost/
是一样的,uri是\ - 匹配结果可以是任何location都没有匹配到的,没有什么默认location的概念
下面通过例子说明:
location = / { 1
[ configuration A ]
}
location / { 2
[ configuration B ]
}
location /documents/ { 3
[ configuration C ]
}
location ^~ /images/ { 4
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ { 5
[ configuration E ]
}
uri是/
:
先进行前缀匹配,按照书写的顺序,进行顺序为1234
的匹配。匹配到1
时,因为满足且是精确匹配,终止匹配,configuration A
。
uri是/index.html
:
先进行前缀匹配,则按照书写的顺序,进行顺序为1234
的匹配,在匹配完成后(1234
都比较了),2
满足,2
是最长前缀匹配(并不是都没匹配到,匹配到“默认”的/这个逻辑,location没有默认的概念)。
然后进行正则匹配,按照书写的顺序,进行顺序为5
的匹配,没有匹配到,选择之前的最长前缀匹配, configuration B
。
uri是/documents/document.html
:
先进行前缀匹配,则按照书写的顺序,进行顺序为1234
的匹配,在匹配完成后(1234
都比较了),2
和3
满足,3
是最长前缀匹配,所以暂时匹配配置configuration C。
然后进行正则匹配,按照书写的顺序,进行顺序为5的匹配,没有匹配到,选择之前的最长前缀匹配, configuration C
。
uri是/images/1.gif
:
先进行前缀匹配,则按照书写的顺序,进行顺序为1234
的匹配,在匹配完成后(1234
都比较了),2
和4
满足,4
是最长前缀匹配,所以暂时匹配配置configuration D。又因为标记了^~
,所以不进行后面的正则匹配,匹配结束,configuration D
。
uri是/documents/1.jpg
:
先进行前缀匹配,则按照书写的顺序,进行顺序为1234
的匹配,在匹配完成后,2
和3
满足,3
是最长前缀匹配,所以暂时匹配配置configuration C
。
然后进行正则匹配,按照书写顺序,进行顺序为5
的匹配,匹配成功,丢弃之前的匹配,选择configuration E
,并终止后面的正则匹配。