先查阅资料 
很多网页都有说明。一遍没有看懂,还是找官网,比较权威。  http://nginx.org/en/docs/http/ngx_http_core_module.html#location  一下是根据网站的意思整理成初步顺序。  
regular expression – Regular expressions are specified with the preceding “~*” modifier (for case-insensitive matching), or the “~” modifier (for case-sensitive matching)  
- first checks locations defined using the prefix strings;
 - location with the longest matching prefix is selected and remembered;
 - If the longest matching prefix location has the “^~” modifier then
  regular expressions are not checked. - regular expressions are checked
 - in the order of their appearance in the configuration file;
 - The search of regular expressions terminates on the first match
 - If no match with a regular expression is found then the
  configuration of the prefix location remembered earlier is used   
只看到正则表达是 ~ ~*,也没有搞懂prefix string是什么意思。  
我们一起来看看nginx plus的介绍:  There are two types of parameter to the location directive: prefix strings (pathnames) and regular expressions  
- Test the URI against all prefix strings.
 - The = (equals sign) modifier defines an exact match of the URI and a
  prefix string. If the exact match is found, the search stops. - If the ^~ (caret-tilde) modifier prepends the longest matching
  prefix string, the regular expressions are not checked. - Store the longest matching prefix string.
 - Test the URI against regular expressions(~ or ~*).
 - Stop processing when the first matching regular expression is found
  and use the corresponding location. - If no regular expression matches, use the location corresponding to
  the stored prefix string.   
nginx plus 第4条和 nginx http module中的第2条意思一样。  
按照语法,这四个表达式可以省略。  location [ = | ~ | ~* | ^~ ] uri { … }  
猜测prefix strings (pathnames),应该是直接使用uri,省略语法中四个表达式。  
在网站中测试下 
https://detailyang.github.io/nginx-location-match-visible/  
location /a {}  location = /a {}  location ^~ /a {}  location ~* /A {}  location ~ /a {}  location /abc {}  访问/ab 匹配到 ^~ /a  访问/abc 还是匹配到 ^~ /a 根据第三条  
删掉 ^~ /a,变成:  location /a {}  location = /a {}  location ~* /A {}  location ~ /a {}  location /abc {}  访问 /abc ,匹配到 ~ /a 根据第五条  
删掉 ~ /a,变成:  location /a {}  location = /a {}  location ~* /A {}  location /abc {}  访问 /abc 匹配到 /abc ,,,不知道为什么没有匹配~* /A,一会测试下。  
找台机器测试下 
server {
    listen 192.168.200.241:80;
    server_name www.a.com;
    location /a { return 200 "matched /a\n"; }
    location = /a { return 200 "matched = /a\n"; }
    location ^~ /ab { return 200 "matched ^~ /ab\n"; }
    location ~* /a { return 200 "matched ~* /a\n"; }
    location ~ /a { return 200 "matched ~ /a\n"; }
    location /abc { return 200 "matched /abc\n"; }  
}
  
star@STAR-LEE:~$ curl http://192.168.200.241/abc  matched ~* /a  star@STAR-LEE:~$ curl http://192.168.200.241/Abc  matched ~* /a  貌似那个网站有些内容不是很准确。  接下来继续测试:  把~* /a移动到~ /a后面  
server {
    listen 192.168.200.241:80;
    server_name www.a.com;
    location /a { return 200 "matched /a\n"; }
    location = /a { return 200 "matched = /a\n"; }
    location ^~ /ab { return 200 "matched ^~ /ab\n"; }
    location ~ /a { return 200 "matched ~ /a\n"; }
    location ~* /a { return 200 "matched ~* /a\n"; }
    location /abc { return 200 "matched /abc\n"; }  
}
  
节约下篇幅。。。  
star@STAR-LEE:~$ curl http://192.168.200.241/Abc  matched ~* /a  star@STAR-LEE:~$ curl http://192.168.200.241/abc  matched ~ /a  说明 ~ 和 ~* 优先级相等。  
突发奇想,在= ,prefix string,^~后面使用perl正则表达式会怎么样。  
server {
    listen 192.168.200.241:80;
    server_name www.a.com;
    location /a { return 200 "matched /a\n"; }
    location = /a { return 200 "matched = /a\n"; }
    location ^~ /ab* { return 200 "matched ^~ /ab\n"; }
    location ~* /a { return 200 "matched ~* /a\n"; }
    location ~ /a { return 200 "matched ~ /a\n"; }
    location /abc { return 200 "matched /abc\n"; }  
}
  
star@STAR-LEE:~$ curl http://192.168.200.241/abc  matched ~* /a  star@STAR-LEE:~$ curl http://192.168.200.241/ab*  matched ^~ /ab  
貌似不是按照正则表达式来的。说明:  只有在~,~*后面可以使用perl的正则表达式。  prefix string , = , ^~ 后面跟正则表达式都无效。  
总结下 
这样匹配顺序就理清楚了:  1.首先用prefix strings走一遍,记录最长匹配;  2.如果被 = 精确匹配,则不再查找;  3.如果 ^~ 匹配的是prefix strings中最长匹配,则不使用正则表达式查找;  4.使用 ~ 或 ~* 匹配到第一个,则不再查找;  5.如果4没有匹配到,使用1中记录的最长匹配;  
来验证一下:  先不使用正则表达式  
server {
    listen 192.168.200.241:80;
    server_name www.a.com;
    location /a { return 200 "matched /a\n"; }
    location = /a { return 200 "matched = /a\n"; }
    location ^~ /ab { return 200 "matched ^~ /ab\n"; }
    # location ~* /a { return 200 "matched ~* /a\n"; }
    # location ~ /a { return 200 "matched ~ /a\n"; }
    location /abc { return 200 "matched /abc\n"; }  
}
  
star@STAR-LEE:~$ curl http://192.168.200.241/a  matched = /a  star@STAR-LEE:~$ curl http://192.168.200.241/ab  matched ^~ /ab  star@STAR-LEE:~$ curl http://192.168.200.241/abc  matched /abc  star@STAR-LEE:~$ curl http://192.168.200.241/abcd  matched /abc  star@STAR-LEE:~$ curl http://192.168.200.241/abd  matched ^~ /ab  
测试下正则表达式的影响: 
server {
    listen 192.168.200.241:80;
    server_name www.a.com;
    location /a { return 200 "matched /a\n"; }
    location = /a { return 200 "matched = /a\n"; }
    location ~* /a { return 200 "matched ~* /a\n"; }
    location ~ /a { return 200 "matched ~ /a\n"; }
    location ^~ /ab { return 200 "matched ^~ /ab\n"; }
    location /abc { return 200 "matched /abc\n"; }  
}
  
star@STAR-LEE:~$ curl http://192.168.200.241/abc  matched ~* /a  location /abc虽然是prefix string中的最长匹配,使用顺序4;  
star@STAR-LEE:~$ curl http://192.168.200.241/abcd  matched ~* /a  location /abc虽然是prefix string中的最长匹配,使用顺序4;  
star@STAR-LEE:~$ curl http://192.168.200.241/abd  matched ^~ /ab  使用顺序3,并且不受位置影响,即使在正则表达式后面也无所谓。  
想起nginx plus location中的一句话:  For a request URI to match a prefix string, it must start with the prefix string.  不知何意,如有好心人知道,还请指点迷经。 
                
                
                
        
        
    
 
 |