前言:最近排查一个nginx配置项不生效的问题,由于对location的配置规则生疏了导致走了弯路,这里整理一下备忘,亦可作为新人的培训教程。
location常用的语法如下:
location [ = | ~ | ~* | ^~ ] uri { ... }
uri前面的修饰符有四种:=、~、~*、^~,再加上默认没有修饰符,共有5种常见规则(@name用法不在本篇讨论范围)。这5种规则又分为两类:前缀字符串匹配和正则表达式匹配。
- = 该修饰符用于前缀字符串匹配,表示精确匹配;
- ^~ 该修饰符用于前缀字符串匹配,如果该修饰符对应的URI是匹配的前缀字符串中最长的,不再进行正则表达式匹配;
- ~ 该修饰符用于正则表达式匹配(大小写敏感);
- ~* 该修饰符用于正则表达式匹配(大小写不敏感);
- 默认uri前面不加修饰符时也用于前缀字符串匹配。
为了更清楚的说明问题,先举几个例子,后面再讲优先级,带着问题看更容易理解:
location = / {
[ configuration A ]
}
location / {
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}
location ^~ /images/ {
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}
“/” 请求会匹配 configuration A, “/index.html” 请求会匹配 configuration B, "/documents/document.html"请求会匹配 configuration C, “/images/1.gif” 请求会匹配configuration D, “/documents/1.jpg” 请求会匹配configuration E.
location的匹配优先级如下:
- 先用所有前缀字符串和目标URI尝试匹配。
- 如果“=”修饰符定义前缀字符串和目标URI精确匹配上,则停止搜索。匹配结束。
- 如果和目标URI匹配的最长前缀字符串前面有“^~”修饰符,则不再检查正则表达式,匹配结束。
- 存储和目标URI匹配的最长的前缀字符串。
- 使用所有的正则表达式和目标URI尝试匹配。
- 当找到第一个匹配的正则表达式时,使用对应的location配置,匹配结束。
- 如果没有找到匹配的正则表达式,则使用4中匹配的最长的前缀字符串的location配置。
综上,优先级从高到低依次为:“=”>“^~”>正则匹配(“~”、“~*”)>一般前缀字符串匹配。