概述
平时使用 Nginx 的过程中,进行最多的可能就是 server 的配置, server 块中通过 listen 指令设置对端口的监听,server_name 指令根据域名进行匹配,确定执行的 server 指令块
进入到 server 块中;在一个 server 块中会配置一个或者多个 location 块。通过对请求 URI 的匹配确定执行的 location 指令块。location 指令只会匹配URI,不会匹配后面的参数。
Location 配置语法
Syntax : location [~|~*|^~|=] uri {...}
: location @name {...}
Default : -
Context : server location
location 指令可以分为以下 3 类:
- 前缀字符串匹配
- 正则表达式匹配
- 用于内部跳转的命名location @
主要需要掌握前两条的规则,以及 location 块的匹配流程。
前缀字符串匹配
前缀字符串匹配根据有无修饰符、修饰符的不同可以分为三种不同的情况
- 无修饰符:常规匹配 URI 的开头
^~修饰符:常规匹配 URI 的开头,不同的是,如果匹配成功则不会进行后续的正则匹配。=修饰符:精确地匹配 URI ,完全一样才会匹配的上
// 等于号(=)修饰符:精确匹配,
location = /aaa {
return 200 'SUCCESS';
}
// 无修饰符:一般常规匹配
location /aaa {
return 200 'SUCCESS';
}
// ^~修饰符 : 匹配上后则不在进行后续的正则表达式匹配
location ^~ /aaa {
return 200 'SUCCESS';
}
正则表达式匹配
正则表达式匹配以 ~ 修饰符开始,后面如果跟 * 表示忽略大小写。
- ~*:忽略大小写
- ~:大小写敏感
// ~* : 忽略大小写
location ~* ss/index.html$ {
return 200 'SUCCESS';
}
// ~ : 大小写敏感
location ~ ss/index.html$ {
return 200 'SUCCESS';
}
匹配流程
整个匹配其实是优先级最高的是精确匹配(=),如果存在精确匹配匹配成功,则使用精确匹配的location
精确匹配不存在,则进行前缀字符串匹配,首先找到最长匹配的前缀字符串,然后看是否以 ^~ 开头,顺序很重要。先确定最长匹配。然后看是否以 ^~ 开头。以 ^~ 开头的如果不是最长匹配肯定不会使用。
确定了最长匹配之后 根据是否以 ^~ 开头来决定是否进行正则匹配。以 ^~ 开头则使用该最长匹配,未以 ^~ 开头,则继续进行正则表达式匹配。
正则表达式匹配时,注意 location 在 nginx.conf 中的前后顺序,在前的优先。如果正则表达式匹配成功,则使用正则表达式匹配的结果,否则使用之前最长匹配的结果。