一文讲清楚Nginx location匹配优先级规则

    Nginx 配置文件中的「server」模块下的子模块 「location」包含了一套与请求 URI 进行匹配的规则,以及「location」匹配成功后的处理逻辑,例如:返回服务器端的静态文件或者实现跳转等功能,可以实现 Nginx 的“动静分离”和“反向代理”等核心功能,所以正确理解「location」匹配规则是非常重要的。以下是Nginx官方文档和翻译文档对「location」模块的解释:

  • 核心模块:Module ngx_http_core_module
  • 翻译内容:ngx_http_core_module 模块

一. 语法规则:

location [=|~|~*|^~] /uri/ { … }   //红色方框里面的参数为可选项,括号里为指令集

    假如 nginx 现在接受到一个 URL 请求:http://www.example.com/static/img/logo.jpg, 这里需要注意,URL从第一个单斜杠后的内容才是「URI」内容:/static/img/logo.jpg,那么location匹配的原理就是用截取的「URI」和location表达式进行匹配和定位,并执行location模块内部的指令集。

一个「location」表达式可以使用「前缀字符串」- prefix string, 或「正则表达式」- regular expression 来定义。

1. 「前缀字符串」:以 = (精确匹配)或 ^~  修饰符开头或者不带任何修饰符的字符串

location = /static/img/logo.jpg {...}

location ^~ /static/img/logo.jpg {...}

location /static/img/logo.jpg {...}

2.  「正则表达式」:以“~*”(不区分大小写),或者“~”(区分大小写)修饰符开头,例如:下面的正则表达式匹配的是以“gif|jpg|jpeg” 文件后缀名结尾的所有URI,\. 代表文件后缀名。

location ~* \.(gif|jpg|jpeg)$ {...}

location ~ \.(gif|jpg|jpeg)$ {...}

二. 匹配规则

  • nginx 首先匹配以「前缀字符串」定义的location,找到匹配成功的最长的前缀字符串,并且记录下来,然后继续匹配「正则表达式」定义的location(按照配置文件里locaton块定义的顺序依次进行匹配)如果匹配成功,则终止匹配。
  • 如果「正则表达式」没有匹配成功,则采用之前记录的匹配成功的最长「前缀字符串」的location.
  • 如果匹配成功的最长「前缀字符串」含有“^~”修饰符,则终止匹配,即不再继续匹配「正则表达式」定义的location路径。
  • 如果location 含有“=”字符,并且与请求的URI精确匹配成功,则终止匹配。

三. 匹配实例

请求URL案例分析:http://www.example.com/static/img/logo.jpg

该请求的URI部分:/static/img/logo.jpg

1. 如果「前缀字符串」定义的location与请求URI“精确匹配”成功,则终止匹配。

location = /static/img/logo.jpg {

}

2. 如果有多个「前缀字符串」匹配成功,则“记住”最长的前缀匹配,即本例中的 /static/img/,并继续检测「正则表达式」匹配。

location /static/ {

}

location /static/img/ {

}

3. 如果匹配成功的最长「前缀字符串」含有“^~”修饰符,则终止匹配。

location /static/ {

}

location ^~ /static/img/ {

}

4. 如果有多个「正则表达式」匹配成功,则放弃上述 2 中的最长前缀匹配,使用第一个匹配成功的正则匹配,即本例中的 location ~* /static/ ,并终止匹配。

location /static/ {

}

location /static/img/ {

}

location ~* /static/ {

}

location ~* /static/img/ {

}

5. 如果没有「正则表达式」满足匹配,则采用 “步骤2” 中记住的最长前缀匹配, 即:本例中的location /static/img/ 。

location /static/ {

}

location /static/img/ {

}

location ~* /video/ {

}

6.  通配规则: location / 可以匹配任何请求,如果未匹配到其他的location,则执行本例中的location /。可以将通配规则理解为 swith case 语句里面的 default 分支。

location / {

}

location /video/ {

}

你可能感兴趣的:(Nginx,nginx,服务器,java)