共计 2977 个字符,预计需要花费 8 分钟才能阅读完成。
一 语法和优先级
语法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
,因为有=
,所以优先匹配,而后完结。
// 输入 4
server {
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 后,则完结匹配。
// 输入 2
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;
}
}
当拜访http://localhost/test/
,匹配到正则后,则完结匹配。不会再往下匹配第三个 location。
// 输入 2
server {
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
// demo1
server {
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;
}
}
// demo2
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 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;
}
}