美文网首页
Nginx Location匹配详解

Nginx Location匹配详解

作者: Se7en的架构笔记 | 来源:发表于2020-03-17 09:35 被阅读0次

1. location语法

Syntax: location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
Default:    —
Context:    server, location

2. 修饰符

  • = 表示精确匹配。只有请求的url路径与后面的字符串完全相等时,才会命中。
    使用=精确匹配可以加快查找的顺序
  • ~ 表示该规则是使用正则定义的,区分大小写。
  • ~* 表示该规则是使用正则定义的,不区分大小写。
  • ^~ 表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找

3. 匹配过程

对请求的url序列化。例如,对%xx等字符进行解码,解析url中的".", "..",并且尽可能地将两个或多个相邻的"/"压缩成一个"/"。这一步是匹配的前置工作。
location有两种表现形式,一种是前缀字符,另一种是正则表达式。正则表达式前面使用修饰符"*~"(大小写不敏感),或者前面使用修饰符 "~"(大小写敏感)。
当收到一个url请求时:

  1. Ngixn首先先检查使用前缀字符定义的location,选择最长匹配的项并记录下来,然后检查正则表达式定义的location。
  • 这里有两个例外:
    1.1 如果找到了精确匹配的location,也就是使用了=修饰符的location,结束查找,使用它的配置。
    1.2 如果通过最长匹配原则匹配到的前缀字符定义的location以"^~"作为修饰符,结束查找,使用它的配置。
  1. 查找使用正则表达式定义的location,如果匹配到location,则立即停止查找,使用它定义的配置。
    如果没有匹配的正则表达式的location,则使用前面记录的最长匹配前缀字符的location。

匹配过程图示

image.png

4. 示例

接下来我们以一个例子来说明具体的匹配过程
配置文件:

location = / {
    [ configuration A ]
}

location / {
    [ configuration B ]
}

location /documents/ {
    [ configuration C ]
}

location ^~ /images/ {
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
}
  • 请求/精准匹配A,不再往下查找。
  • 请求/index.html匹配B。首先查找匹配的前缀字符,找到最长匹配是配置B,接着又按照顺序查找匹配的正则。结果没有找到,因此使用先前标记的最长匹配,即配置B。
  • 请求/documents/document.html匹配C。首先找到最长匹配C,由于后面没有匹配的正则,所以使用最长匹配C。
  • 请求/images/1.gif匹配D。首先进行前缀字符的查找,找到最长匹配D。但是,特殊的是它使用了^~修饰符,不再进行接下来的正则的匹配查找,因此使用D。这里,如果没有前面的修饰符,其实最终的匹配是E。
  • 请求/documents/1.jpg匹配E。首先进行前缀字符的查找,找到最长匹配项C,继续进行正则查找,找到匹配项E。

5. location @的用法

@用来定义一个命名location。主要用于内部重定向,不能用来处理正常的请求。其用法如下:

location / {
    try_files $uri $uri/ @redirectUri
}
location @redirectUri {
    # ...do something
}

上例中,当尝试访问url找不到对应的文件就重定向到我们自定义的命名location(此处为redirectUri)。
值得注意的是,命名location中不能再嵌套其它的命名location。

6. 关于URI末尾的/

如果一个location由前缀字符定义,该location以"/"结尾,并且通过
proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass, grpc_pass中的方法对请求进行处理 ,如果请求中的URI等于这个字符,但是末尾没有"/",返回的结果将会在URI的末尾加上"/",进行301重定向。如果你不想让重定向发生,那么在location的前缀字符最后就不要加"/"。

location /user/ {     #重定向
    proxy_pass http://user.example.com/;  #注意这里最后的"/"要加
}

location = /user {   #不重定向
    proxy_pass http://login.example.com/;  #注意这里最后的"/"要加
}

如果URI的尾部如果缺少/将导致重定向。因为根据约定,URL尾部的/表示目录,没有/表示文件。所以访问/some-dir/时,服务器会自动去该目录下找对应的默认文件。如果访问/some-dir的话,服务器会先去找some-dir文件,找不到的话会将some-dir当成目录,重定向到/some-dir/,去该目录下找默认文件。

相关文章

网友评论

      本文标题:Nginx Location匹配详解

      本文链接:https://www.haomeiwen.com/subject/txlgehtx.html