Nginx 的 location 的匹配规则
location 是 Nginx 的块级指令,用作匹配不同的 URL 请求做不同的业务处理。其中较为难理解的是 location 的匹配顺序。
序言
location 在 Nginx 中用来匹配从客户端发送过来的不同请求,从而匹配不同的资源,是 Nginx 中一个很重要的指令。location 有两种语法:
location @name {
...
}
第一种方式比较简单, @name
表示自己定义的一个名称,通常用作 Nginx 的内部跳转:
error_page 404 = @404;
location @404 {
proxy_pass http://oldme.net;
}
如示例,当访问的 URL 不存在时,就会重定向到 http://oldme.net
第二种方式是分为四个部分: location
+ 匹配符号
+ URL
+ 处理逻辑。其中匹配规则又分为四种,且五种匹配方式有着不同的优先级顺序。这种方式是最常见的匹配方式,也是本文的重点所在。而四种匹配方式又分为普通匹配和正则匹配,如果你不了解正则,可以先学习一下:正则表达式从入门到高级。
location [ = | ~ | ~* | ^~ ] URL {
...
}
普通匹配
精准匹配
精准匹配使用 =
匹配符号,表示只有 URL
全部对应才能匹配到。精准匹配优先级最高,一旦命中,直接返回。
location = /list {
...
}
http://oldme.net/list 匹配成功
http://oldme.net/list/ 匹配失败(注意最后的/)
http://oldme.net/list/1 匹配失败
http://oldme.net/article/list/1 匹配失败
前缀匹配
前缀匹配使用 ^~
匹配符号,表示匹配 URL 的前缀部分。会优先匹配前缀最长的 location,且区分大小写。命中前缀后直接返回,不在执行后续的匹配规则,优先级仅次于精准匹配,优先级第二。
location ^~ /pre {
[pre]
}
location ^~ /pre/pre2 {
[pre2]
}
http://oldme.net/pre 匹配[pre]
http://oldme.net/pre123 匹配[pre]
http://oldme.net/Pre 不匹配
http://oldme.net/pre/pre2/1 匹配[pre2]
前缀匹配也可以使用无符号的匹配方式,但是优先级最低,处于正则之后,排在第四。
使用 ^~
和 无符号匹配
的最大区别就是一个处于正则匹配之前,一个处于正则匹配之后。
location /pre {
[pre]
}
Nginx 如果运行在 Windows 下,精准匹配和前缀匹配是不区分大小写的。
正则匹配
正则匹配两种匹配方式的优先级都处在第三方,低于 ~^
前缀匹配,高于 无符号前缀匹配。匹配顺序就按照文件中的顺序来匹配。
~ 代表的是区分大小写的正则匹配,~* 代表不区分大小写的正则匹配。
location ~ /Pre/ {
...
}
http://oldme.net/Pre/ 匹配
http://oldme.net/Pre 不匹配
http://oldme.net/pre 不匹配
http://oldme.net/article/Pre/ 匹配
location ~* /Pre/ {
...
}
http://oldme.net/Pre/ 匹配
http://oldme.net/pre/ 匹配
http://oldme.net/Pre 不匹配
http://oldme.net/pre 不匹配
http://oldme.net//article/pre/ 匹配
匹配顺序
=
精准匹配^~
前缀匹配,会优先匹配最长的前缀~
和~*
正则匹配,匹配顺序按照文件中的位置- 无符号前缀匹配,会优先匹配最长的前缀
location 结尾带不带/
location
结尾带不带斜杠(/)是有区别的。如果 location
结尾带斜杠,例如:
location /exp/ {
// 处理以 /exp/ 开头的 URL 的配置
}
那么这个 location
将匹配所有以 /exp/
开头的 URL
,包括 /exp/
本身和 /exp/a
、/exp/b
等 URL
。注意,这里的斜杠表示一个目录,即表示匹配以 /exp/
开头的 URL
,并且后面必须跟着一个目录或者 URL
末尾。
如果 location
结尾不带斜杠,例如:
location /exp {
// 处理以 /exp 开头的 URL 的配置
}
那么这个 location
将匹配所有以 /exp
开头的 URL
,包括 /exp
本身和 /exp/a
、/exp/b
等 URL
。这里的斜杠表示一个字符,即表示匹配以 /exp
开头的 URL
,并且后面可以跟着任意字符。
本文目录