一 语法和优先级

语法
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;    }}