nginx的location

122 篇文章 1 订阅
120 篇文章 1 订阅

前言

Nginx的location就相当于url路由,Nginx根据location的配置来决定究竟如何处理一个请求。

Nginx通过将一个请求的url与location进行对比,来决定将该请求扔到哪个location对应的处理策略中。

一、location的匹配规则

文档:Module ngx_http_core_module

上面是文档,我将location的简单的总结为以下几点:

概念:

Nginx的location分为两类:一类是prefix string;另一类是regular expression。

**location**?[?`=`|`~`|`~*`|`^~`]`_uri_`{ ... }
**location**?`@``_name_`{ ... }

什么是prefix string

不以 ~* ,~,@开头的location。

默认大小写敏感。

例如:

location = / {
[ configuration A ]
}

#上面是精准匹配(exact URI),这种匹配会匹配完整的URI。也就是只有当URI为/的时候,才会命中。

location / {
[ configuration B ]
}

location /documents/ {
[ configuration C ]
}

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

这些都是prefix string location。

精准匹配:=开头,后面跟上路径,这种location必须URI与location完全相等,然后才能匹配命中。

排除正则匹配:以^~开头,后面跟上路径,这种location一旦匹配命中,Nginx便不再进行正则匹配。

普通的匹配:直接以路径开头。

这三种location都是prefix string location,对于prefix string location 的匹配来说,Nginx选取与request的URI相似程度最高的prefix string location作为longest match prefix string。

以上面的location为例:

/test/test2将命中location /。

/将命中location = /。

/documents/test1/test2和/documents/将命中 location /documents/。

/images/test1/test2将命中location ^~ /images/。

什么是regular expression?

即以~* ,~开头的location,它们表示这是一个正则表达式。

其中*表示大小写不敏感,表示大小写敏感。

例如:

location ~* .(gif|jpg|jpeg)$ {
[ configuration E ]
} #大小写不敏感

location ~ .(Gif|jPg|jpeg)$ {
[ configuration E ]
} #大小写敏感

正则表达式匹配中,大小写敏感的优先级更高,所以Nginx总是先测试大小写敏感的正则。

Nginx采用的PCRE正则表达式。

PCRE是Perl的兼容正则表达式(实际上并不是完全兼容,会有所区别。)。

文档:

A Regular Expression Tester for NGINX and NGINX Plus - NGINX

https://www.pcre.org/

PCRE的正则文档

perlretut - Perl regular expressions tutorial - Perldoc Browser

perlre - Perl regular expressions - Perldoc Browser

特殊的location

以@开头的location,叫做named location,它不参与location的匹配,但是它可以直接被其他directive调用。

主要作用就是在别的指令中,直接将一个request传递给该location处理。

因此,我在开头并没有将它算作一类location,在我眼里,它只是一个类似于PL的语法糖的东西。

典型应用:

1、错误处理

error_page 404 = @fallback;
location @fallback {
proxy_pass http://www.linuxhub.org;
}

2、如果URI不存在,则把请求代理到www.linuxhub.org上去做个弥补

location / {
try_files $uri @linuxhub;
}
location @linuxhub {
proxy_pass http://www.linuxhub.org;
}

匹配规则:

对于prefix string location 的匹配来说,Nginx选取与request的URI相似程度最高的prefix string location作为longest match prefix string。

总的来说,匹配过程分为两个阶段:第一阶段是Prefix String匹配;第二阶段是正则匹配。

对于第一阶段来说,

首先比较精准匹配,如果精准匹配命中,直接结束匹配过程,该精准匹配作为此次location匹配的结果;如果精准匹配没命中,则比较其他Prefix String Location。

比较其它的Prefix String Location,其遵循如下:

依次比较location,选取与URI相似度最高的,匹配路径最长的location作为longest match prefix location;如果该longest match prefix location是一个排除正则表达式(即^~开头)的location,那么就会结束匹配过程,该location命中。

如果该longest match prefix location不是一个排除正则表达式(即^~开头)的location,那么就进入正则匹配阶段。

对于第二阶段来说,

正则匹配阶段很简单,那就是按照配置文件,自上而下一次匹配,如果命中,则结束匹配过程,命中的location作为。否则,如果直到结束都没有命中,那么此时就选用第一阶段的longest match prefix location作为此次location匹配的结果。

二、location匹配中的一些坑

浏览器中的输入:

www.test.com

那么实际上的URI会是http://www.test.com/,没错,会自动在后面添加一个/。顶级域名后面会自动添加顶级路径。

浏览器中输入:

www.test.com/test1

那么实际上的URI会是http://www.test.com/test1。域名后面如果已经添加了顶级域名,则后面不会自动添加一个/。

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

重点坑:

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

三、如何编写location

按照上面的匹配规则,可以按照如下配置location:

1、最前面写精准匹配规则

精准匹配规则一般配置给高频URI,提高匹配效率。例如首页,登录页等。

2、接着写排除正则的匹配规则

排除正则匹配可以配置给一般路径资源,这样可以提高匹配效率,因为一旦命中,3就不会执行了。

一般来说,有什么需要添加的URI匹配,都优先添加到这一块。

3、接着写正则匹配

正则匹配一般配置给一些特殊路径的资源。

可以有多条正则,越精确的正则应该越放到前面,因为正则一旦命中,直接下面的正则就不匹配了。

4、默认的根路径匹配

这个和1以及2都是属于prefix string location匹配,一旦1,2,3都不命中,那么最后就会匹配到这里了。

如下:

location = /  {
#规则A #一般首页会非常频繁,所以设置精准匹配,提高匹配效率。
}

location = /login {
#规则B  #一般登录页也会非常频繁,所以设置精准匹配,提高匹配效率。
}

location ^~ /static/ {
#规则C  #一般来说,静态资源是访问最多的URI,所以放在这里。
}


#对于有某些特殊路径或后缀的资源,写在正则匹配中。
location ~ .(gif|jpg|png|js|css)$ {
#规则D
}

location ~* .png$ {
#规则E
}



#默认的根路径匹配,上面的都不命中的URI,全部都走这里。
location / {
#规则H
}

按照上面这样编写,思路清晰,便于维护

路径的匹配优先级一目了然,URI的路径匹配自上而下,只要命中获得结果,就终止匹配流程,匹配效率也极高。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鱼香Ross

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值