Nginx之 location 详解

一、知识准备

需要掌握Nginx 的基本知识,同时对nginx.conf 有一定的了解

二、简介

  1. Nginx 是一款反向代理工具,将客户端请求进行拦截,然后转发到后台其他服务器进行处理,其中Nginx.conf 是核心,在里面可以配置 :集群、最大并发数、https ssl、反向代理服务器、请求头的配置、跨域、POST/GET 请求方式 等

  2. nginx 先监听 ip (IP 没匹配 再匹配域名),后监听端口,最后匹配location。

三、详解

1. location语法规则

location [=|~|~*|^~]/uri/{}
# |指令|   | 前缀 |  |匹配的网站网址|  |匹配URI之后要执行的配置段|
语法匹配规则备注
=精确(严格)匹配一旦匹配成功,则不再查找其他匹配项
^~非正则匹配(依然遵循最大前缀匹配规则)一旦匹配成功,则不再查找其他匹配项
~开头表示区分大小写的正则匹配如果有多个location的正则能匹配的话,则使用正则表达式最长的那个
~*开头表示不区分大小写的正则匹配如果有多个location的正则能匹配的话,则使用正则表达式最长的那个
!~ 和 !~*分别为区分大小写不匹配及不区分大小写不匹配的正则如果有多个location的正则能匹配的话,则使用正则表达式最长的那个
没有前缀普通匹配(遵循最大前缀匹配规则)相同类型的表达式,字符串长的会优先匹配
/通用匹配,任何请求都会匹配到
@通用匹配,任何请求都会匹配到定义一个命名的 location,使用在内部定向时,例如 error_page, try_files

2. 分类

两类:正则location和普通location

  • ~ 、~*、!~、!~* 为正则location
  • =、^~、@和无任何前缀的都属于普通location,另外,@是用作服务端内部的一种转发行为,很少用.。

3. 匹配优先级

第一优先级:等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他匹配项;否则继续查找第二优先级。
第二优先级:^~类型表达式。一旦匹配成功,则不再查找其他匹配项;否则查找第三优先级。
第三优先级:正则表达式类型(~ ~* !~ !~*)的优先级次之。如果有多个location的正则能匹配的话,则使用正则表达式最长的那个;否则查找第四优先级
第四优先级:常规字符串匹配类型。按最大前缀匹配;否则查找第五优先级。
第五优先级/ 匹配,所有的请求都会匹配到。

备注:

  1. “普通location ”与“正则location ”之间的匹配规则是:先匹配普通location ,再匹配正则location 。那么,“普通location ”内部(普通location 与普通location)是如何匹配的呢?简单的说:最大前缀匹配。意思是普通location先匹配,而且选择了最大前缀匹配后,不能就停止后面的匹配,最大前缀匹配只是一个临时的结果,nginx还需要继续检查正则location。

  2. 正则location ”与“正则location”内部的匹配规则是:按照正则location 在配置文件中的物理顺序(编辑顺序)匹配的(这句话就说明location 并不是一定跟顺序无关,只是普通location与顺序无关,正则location 还是与顺序有关的),并且只要匹配到一条正则location ,就不再考虑后面的(这与“普通location”与“正则location”之间的规则不一样, “普通location”与“正则location”之间的规则是:选择出“普通location ”的最大前缀匹配结果后,还需要继续搜索正则location )。

  3. 最大前缀匹配,如果继续搜索的“正则location”也有匹配上的,那么“正则location”会覆盖“普通location”的最大前缀匹配(因为有这个覆盖关系,所以造成有些同学以为正则location先于普通location执行的错误理解)

  4. 通常的规则是,匹配完了“普通location”指令,还需要继续匹配“正则location”,但是你也可以告诉Nginx:匹配到了“普通location”后,不再需要继续匹配“正则location”了,要做到这一点只要在“普通location”前面加上^~符号(^表示“非”,~表示“正则”,字符意思是:不要继续匹配正则)。

  5. 除了上面的^~可以阻止继续搜索正则location 外,还可以使用=。那么如果^~和=都能阻止继续搜索正则location 的话,那它们之间有什么区别呢? 区别很简单,共同点是它们都能阻止继续搜索正则location,不同点是^~依然遵守“最大前缀”匹配规则,然而=不是“最大前缀”,而是必须是严格匹配(exact match )。

4.举例

<hr/>

```conf
location = / {
  # 精确匹配 / ,主机名后面不能带任何字符串
  [ configuration A ]
}

location / {
  # 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
  # 但是正则和最长字符串会优先匹配
  [ configuration B ]
}

location /documents/ {
  # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
  # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
  [ configuration C ]
}

location ~ /documents/Abc {
  # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
  # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
  [ configuration CC ]
}

location ^~ /images/ {
  # 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。即使是例如 /images/abc 这种普通的最长匹配,也停止。
  [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
  # 匹配所有以 gif,jpg或jpeg 结尾的请求
  # 然而,所有请求 /images/ 下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则
  [ configuration E ]
}

location /images/ {
  # 字符匹配到 /images/,继续往下,会发现 ^~ 存在
  [ configuration F ]
}

location /images/abc {
  # 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在
  # FG的放置顺序是没有关系的
  [ configuration G ]
}

location ~ /images/abc/ {
  # 只有去掉 config D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用
  [ configuration H ]
}


/ -> config A  #精确完全匹配,即使/index.html也匹配不了
/downloads/download.html -> config B    #匹配B以后,往下没有任何匹配,采用B
/images/1.gif -> configuration D   # 匹配到F,往下匹配到D,停止往下
/images/abc/def -> config D  #最长匹配到G,往下匹配D,停止往下   
                   可以看到 任何以/images/开头的都会匹配到D并停止,FG写在这里是没有任何意义的,H是永远轮不到的,这里只是为了说明匹配顺序
/documents/document.html -> config C    #匹配到C,往下没有任何匹配,采用C
/documents/1.jpg -> configuration E     #匹配到C,往下正则匹配到E
/documents/Abc.jpg -> config CC    #最长匹配到C,往下正则顺序匹配到CC,不会往下到E

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值