一 语法和优先级
语法location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
location 前面第一个参数是可选的。=
是准确匹配。当匹配到了,则完结。^
是正则匹配,辨别大小写。^*
是正则匹配,不辨别大小写。^~
是前缀匹配。
第一个参数不填,前面跟着/uri
。此时也是前缀匹配。只是优先级在正则匹配之后。
第一个参数不填,前面跟着/
。此时也是前缀匹配。只是优先级在所有匹配之后。也就是都匹配不到,则匹配该location。
示例配置如下:
location /uri { # ...}location / { # ...}
优先级:
当配置文件中有=
,优先匹配该location,匹配到了,则完结匹配。匹配不到,则先找是否有^~
。
有^~
,则优先匹配该location。匹配到了,则完结匹配。匹配不到,则依照配置文件程序,从上到下匹配。
先匹配第一个正则,匹配到了,则完结。
匹配不到,则往下匹配。
如果没有一个正则都匹配不到,则匹配/uri
。有,则匹配该location,而后完结。如果没有,则匹配/
。有,则匹配该location,而后完结。没有,则提醒404。
所以把=
放到第一个地位,能进步匹配速度。
另外,location的所有匹配,都只对不带参数的申请的uri进行匹配的。
也就是/test
和/test?a=1
是一样的。
二 测试代码
1 准确匹配
拜访 http://localhost/test.png
,因为有=
,所以优先匹配,而后完结。
// 输入4server { listen 80; server_name localhost; location ^~ /test.png { add_header Content-Type 'text/html;charset=utf-8'; return 200 1; } location ~ /test.png { add_header Content-Type 'text/html;charset=utf-8'; return 200 2; } location ~* /test.png { add_header Content-Type 'text/html;charset=utf-8'; return 200 3; } location = /test.png { add_header Content-Type 'text/html;charset=utf-8'; return 200 4; }}
2 前缀匹配
^~
: 优先前缀匹配/
: 前缀匹配
最长匹配:指的是前缀匹配/
,当有多个匹配的时候,先记住以后匹配,持续往下匹配,如果没有正则和优先前缀匹配,则始终匹配到最初一个location,而后应用最长匹配到的location。
拜访http://localhost/test/txt/tt
,匹配到第一个后,持续往下匹配。因为没有其余正则和优先前缀匹配,所以始终到第三个匹配,匹配到了,则完结。没匹配到,则以下面匹配的为准。
当拜访http://localhost/test/txt/
,则会把三个location都匹配完,才抉择最长匹配到的location。
所以,如果应用/
前缀匹配的时候,绝对会慢一些。
server { listen 80; server_name localhost; location /test/ { add_header Content-Type 'text/html;charset=utf-8'; return 200 1; } location /test/txt/ { add_header Content-Type 'text/html;charset=utf-8'; return 200 2; } location /test/txt/t { add_header Content-Type 'text/html;charset=utf-8'; return 200 3; }}
当/
前缀匹配上面有优先前缀匹配或者正则,匹配到了,则完结。
当拜访http://localhost/test/txt/
,到第二个location后,则完结匹配。
// 输入2server { listen 80; server_name localhost; location /test/ { add_header Content-Type 'text/html;charset=utf-8'; return 200 1; } location ^~ /test/txt/ { add_header Content-Type 'text/html;charset=utf-8'; return 200 2; }}
当拜访http://localhost/test/
,匹配到正则后,则完结匹配。不会再往下匹配第三个location。
// 输入2server { listen 80; server_name localhost; location /test/ { add_header Content-Type 'text/html;charset=utf-8'; return 200 1; } location ~ /test/ { add_header Content-Type 'text/html;charset=utf-8'; return 200 2; } location ~ /test/txt/ { add_header Content-Type 'text/html;charset=utf-8'; return 200 3; }}
优先匹配^~
跟在配置文件的程序无关。以下两种状况后果是一样的。
当拜访 http://localhost/test.png
,都输入1
// demo1server { listen 80; server_name localhost; location ^~ /test.png { add_header Content-Type 'text/html;charset=utf-8'; return 200 1; } location ~ /test.png { add_header Content-Type 'text/html;charset=utf-8'; return 200 2; }}// demo2server { listen 80; server_name localhost; location ~ /test.png { add_header Content-Type 'text/html;charset=utf-8'; return 200 2; } location ^~ /test.png { add_header Content-Type 'text/html;charset=utf-8'; return 200 1; }}
3 正则匹配
正则匹配,从上到下,匹配到了,则完结。
拜访 http://localhost/test.png
,因为匹配到了第一个正则,所以就完结了。页面输入2
server { listen 80; server_name localhost; location ~ /test.png { add_header Content-Type 'text/html;charset=utf-8'; return 200 2; } location ~ /test.png { add_header Content-Type 'text/html;charset=utf-8'; return 200 3; } location ~ /test.png { add_header Content-Type 'text/html;charset=utf-8'; return 200 4; }}