一文弄懂Nginx的location匹配的实现

 更新时间:2020年02月06日 09:32:48   作者:快狗打车前端团队  
这篇文章主要介绍了一文弄懂Nginx的location匹配的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

由于团队在进行前后端分离,前端接管了 Nginx 和 node 层,在日常的工作中,跟 Nginx 打交道的时候挺多的。其中 location 是使用最多和改动最多的地方。之前对 location 的匹配规则是一知半解的。为了搞明白 location 是如何匹配的,特意花了点时间查了些资料,总结此文。希望能给大家带来帮助。

语法规则

location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }

语法规则很简单,一个location关键字,后面跟着可选的修饰符,后面是要匹配的字符,花括号中是要执行的操作。

修饰符

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

匹配过程

对请求的 url 序列化。例如,对%xx等字符进行解码,去除 url 中多个相连的/,解析 url 中的.,..等。这一步是匹配的前置工作。

location 有两种表示形式,一种是使用前缀字符,一种是使用正则。如果是正则的话,前面有~或~*修饰符。

具体的匹配过程如下:

首先先检查使用前缀字符定义的 location,选择最长匹配的项并记录下来。

如果找到了精确匹配的 location,也就是使用了=修饰符的 location,结束查找,使用它的配置。

然后按顺序查找使用正则定义的 location,如果匹配则停止查找,使用它定义的配置。

如果没有匹配的正则 location,则使用前面记录的最长匹配前缀字符 location。

基于以上的匹配过程,我们可以得到以下两点启示:

  1. 使用正则定义的 location 在配置文件中出现的顺序很重要。因为找到第一个匹配的正则后,查找就停止了,后面定义的正则就是再匹配也没有机会了。
  2. 使用精确匹配可以提高查找的速度。例如经常请求/的话,可以使用=来定义 location。

示例
接下来我们以一个例子来具体说明一下匹配过程。

假如我们有下面的一段配置文件:

location = / {
  [ configuration A ]
}

location / {
  [ configuration B ]
}

location /user/ {
  [ configuration C ]
}

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

location ~* \.(gif|jpg|jpeg)$ {
  [ configuration E ]
}

请求/精准匹配 A,不再往下查找。

请求/index.html匹配 B。首先查找匹配的前缀字符,找到最长匹配是配置 B,接着又按照顺序查找匹配的正则。结果没有找到,因此使用先前标记的最长匹配,即配置 B。

请求/user/index.html匹配 C。首先找到最长匹配 C,由于后面没有匹配的正则,所以使用最长匹配 C。

请求/user/1.jpg匹配 E。首先进行前缀字符的查找,找到最长匹配项 C,继续进行正则查找,找到匹配项 E。因此使用 E。

请求/images/1.jpg匹配 D。首先进行前缀字符的查找,找到最长匹配 D。但是,特殊的是它使用了^~修饰符,不再进行接下来的正则的匹配查找,因此使用 D。这里,如果没有前面的修饰符,其实最终的匹配是 E。大家可以想一想为什么。

请求/documents/about.html匹配 B。因为 B 表示任何以/开头的 URL 都匹配。在上面的配置中,只有 B 能满足,所以匹配 B。

location @name 的用法

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

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

上例中,当尝试访问 url 找不到对应的文件就重定向到我们自定义的命名 location(此处为 custom)。

值得注意的是,命名 location 中不能再嵌套其它的命名 location。

URL 尾部的/需不需要

关于 URL 尾部的/有三点也需要说明一下。第一点与 location 配置有关,其他两点无关。

location 中的字符有没有/都没有影响。也就是说/user/和/user是一样的。

如果 URL 结构是https://domain.com/的形式,尾部有没有/都不会造成重定向。因为浏览器在发起请求的时候,默认加上了/。虽然很多浏览器在地址栏里也不会显示/。这一点,可以访问baidu验证一下。

如果 URL 的结构是https://domain.com/some-dir/。尾部如果缺少/将导致重定向。因为根据约定,URL 尾部的/表示目录,没有/表示文件。所以访问/some-dir/时,服务器会自动去该目录下找对应的默认文件。如果访问/some-dir的话,服务器会先去找some-dir文件,找不到的话会将some-dir当成目录,重定向到/some-dir/,去该目录下找默认文件。可以去测试一下你的网站是不是这样的。

总结

location 的配置有两种形式,前缀字符和正则。查找匹配的时候,先查找前缀字符,选择最长匹配项,再查找正则。正则的优先级高于前缀字符。

正则等查找是按照在配置文件中的顺序进行的。因此正则等顺序很重要,建议越精细的放的越靠前。

使用=精准匹配可以加快查找的顺序,如果根域名经常被访问等话建议使用=。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Nginx虚拟主机的配置实现

    Nginx虚拟主机的配置实现

    虚拟主机指的就是一个独立的站点配置,是nginx默认支持的一个功能,本文主要介绍了Nginx虚拟主机的配置实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • windows7下安装PHP+nginx的方法

    windows7下安装PHP+nginx的方法

    这篇文章主要介绍了windows7下安装PHP+nginx的方法,较为详细的分析了Windows7环境下安装php与nginx服务器环境的具体步骤与相关设置技巧,需要的朋友可以参考下
    2016-05-05
  • Nginx访问控制与参数调优的方法

    Nginx访问控制与参数调优的方法

    这篇文章主要介绍了Nginx访问控制与参数调优的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-03-03
  • Linux上搭载Nginx负载均衡配置使用案例详解

    Linux上搭载Nginx负载均衡配置使用案例详解

    这篇文章主要介绍了Linux上搭载Nginx负载均衡配置使用案例详解,针对此情况而衍生出来的一种廉价有效透明的方法以扩展现有网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性的技术就是负载均衡(Load Balance),需要的朋友可以参考下
    2022-01-01
  • Nginx-rewrite模块概述

    Nginx-rewrite模块概述

    从功能上看 rewrite 和 location 似乎有点像,都能实现跳转,主要区别在于 rewrite 是在同一域名内更改获取资源的路径,这篇文章主要介绍了Nginx-rewrite模块详细介绍,需要的朋友可以参考下
    2023-06-06
  • 使用Bash脚本和Logrotate实现Nginx日志切割的方法

    使用Bash脚本和Logrotate实现Nginx日志切割的方法

    Logrotate是一个Linux系统上用来管理日志文件的工具,它可以定期轮转日志文件、压缩旧的日志文件以及删除过期的日志文件,这篇文章主要介绍了使用Bash脚本和Logrotate实现Nginx日志切割,需要的朋友可以参考下
    2024-05-05
  • 详解基于CentOS 7配置Nginx自启动

    详解基于CentOS 7配置Nginx自启动

    这篇文章主要介绍了详解基于CentOS 7配置Nginx自启动,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • 阿里云Linux系统Nginx配置多个域名的方法详解

    阿里云Linux系统Nginx配置多个域名的方法详解

    本篇文章主要介绍了阿里云Linux系统Nginx配置多个域名的方法详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • nginx proxy_redirect https配置后端http302跳转处理方式

    nginx proxy_redirect https配置后端http302跳转处理方式

    这篇文章主要介绍了nginx proxy_redirect https配置后端http302跳转处理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • 在Nginx服务器下配置StartSSL和SSL的教程

    在Nginx服务器下配置StartSSL和SSL的教程

    这篇文章主要介绍了在Nginx服务器下配置StartSSL和SSL的教程,其中申请证书的步骤确实比较麻烦一些,不过出于安全考虑:p需要的朋友可以参考下
    2015-07-07

最新评论