Nginx的路由功能实现由location来完成,根据location匹配的路径执行内部指令。
location对url的匹配语法:
location [=|~|~*|^~] /uri/ { … }
1、=:表示精准匹配
2、普通匹配
2.1 、~:区分大小写
2.2、~*:不区分大小写
2.3^~:非正则表达式匹配
3、\$:正则表达式
其中优先级为精准匹配>普通匹配>正则表达式。但是最终使用哪个路径不是简简单单的优先级就决定了。下面会根据实例慢慢分析。
1、标准匹配,如果都能匹配到,则nginx会选择最长匹配返回。而且精准匹配不会被其他普通匹配或者正则表达式覆盖。
location = /equal/a {
echo '/equal/a';
}
location = /equal/a/b {
echo '/equal/a/b';
}
location = /equal/a/b/c {
echo '/equal/a/b/c';
}
curl http://water.com/equal/a/b则会输出 /equal/a/b
curl http://water.com/equal/a/b/c则会输出 /equal/a/b/c
2、普通匹配,如果都能匹配到,则nginx会选择最长匹配返回。与精准匹配类似,但是普通匹配有可能被正则表达式覆盖。
location /match/a{#命中,当不是最长
echo '/match/a';
}
location /match/a/b {#命中,当不是最长
echo '/match/a/b';
}
location /match/a/b/c {#命中,是最长
echo '/match/a/b/c';
}
location /match/a/b/c/d {#命中,当不是最长
echo '/match/a/b/c/d';
}
普通匹配(非正则表达式)不会被正则表达式,因为普通匹配的的非正则表达式已经声明不使用正则表达式,所以不不会被正则覆盖。
location ^~ /re/a/b{#普通匹配-非正则匹配,访问/re/a/b开头的路径,不会被后面的正则覆盖
echo 'match ^~ /re/a/b*';
}
location /re/a.html{#普通匹配,访问/re/a.html,会被后面的正则覆盖
echo 'match /re/a.html';
}
location ~ /rex/a/(.*)\.(html|js|css)$ {#正则表达式,覆盖/re/a.html路径,但是不会覆盖 ^~ /re/a/b
echo 'match second';
}
3、正则表达式,如果出现多个正则表达式匹配,则以出现的顺序为准
#正则匹配,括号里变量替换$1,$2
location ~ /re/(.*)\.(html|js|css)$ {#覆盖/re/a.html路径
echo 'cover /re/$1.$2';
}
#正则表达式匹配,以出现顺序为准
location ~ /rex/(.*)\.(html|js|css)$ {#覆盖/re/a.html路径
echo 'match first';
}
location ~ /rex/a/(.*)\.(html|js|css)$ {#覆盖/re/a.html路径
echo 'match second';
}
location ~ /rex/a/b/(.*)\.(html|js|css)$ {#覆盖/re/a.html路径
echo 'match third';
}
由此我们发现,基本优先级是精准匹配>普通匹配>正则表达式,但是不是绝对的,因为普通匹配又是有可能被正则表达式覆盖的。