八、location匹配规则

一、location区块说明

Nginx由内核和模块组成,其中内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端的请求映射到一个location block,而location是Nginx配置中的一个指令,用于访问的URL匹配,而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。

默认Nginx.conf配置文件中至少存在一个location /,即表示客户端浏览器请求的URL为:域名+/,如果location /newindex/,则表示客户端浏览器请求的URL为:域名+/newindex/。

location 是在 server 块中配置,用来通过匹配接收的uri来实现分类处理不同的请求,如反向代理,取静态文件等 location 在 server 块中可以有多个,且是有顺序的,会被第一个匹配的 location 处理 localtion 匹配功能只做匹配分发用,并不会改变uri的内容或其他作用。 简单来说location区块就是用于定位或者匹配网站资源信息。

location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射;ngnix会根据用户请求的URI来检查定义的所有location,并找出一个最佳匹配,而后应用其配置
示例:
server {...
   server_name www.magedu.com;
   location /images/ {
      root /data/imgs/;
   }
}
http://www.magedu.com/images/logo.jpg
--> /data/imgs/images/logo.jpg

二、Location匹配URL的方式

=                                 字面精确匹配;
~                                 最大前缀匹配;
/                                 不带任何前缀:最大前缀匹配;
~                                 大小写相关的正则匹配;
~*                                大小写无关的正则匹配;
@                                location内部重定向的变量。

location [ = | ~ | ~* | ^~ ] uri { ... }
=     --- 精确匹配网站uri资源信息
~     --- 区分大小写匹配网站uri资源信息
~*    --- 不区分大小写匹配网站uri资源信息
^~    --- 优先匹配网站uri资源信息
/ywx/  --- 指定匹配网站资源目录信息
/     --- 默认匹配网站资源信息
!     --- 对匹配的内容进行取反

马哥教育location说明
= 对URI做精确匹配;
location = / {
...
}
http://www.magedu.com/ 匹配
http://www.magedu.com/index.html 不匹配
^~ 对URI的最左边部分做匹配检查,不区分字符大小写
~  对URI做正则表达式模式匹配,区分字符大小写
~* 对URI做正则表达式模式匹配,不区分字符大小写
不带符号 匹配起始于此uri的所有的uri
\ 转义符,可将 . * ?等转义为普通符号

匹配优先级从高到低:
=, ^~, ~/~*, 不带符号

其中Location =、^~、/属于普通字符串匹配,Location ~、~*属于正则表达式匹配,Location优先级与其在Nginx.conf配置文件中的先后顺序无关。

Location = 精确匹配会第一个被处理,如果发现精确匹配,Nginx则停止搜索其他任何Location的匹配。

普通字符匹配,正则表达式规则和完整URL规则将被优先和查询匹配,^~为最大前缀匹配,如果匹配到该规则,Nginx则停止搜索其他任何Location的匹配,否则nginx会继续处理其他location指令。

正则匹配"~"和"~*",如果找到相应的匹配,则Nginx停止搜索其他任何Location的匹配;当没有正则表达式或者没有正则表达式被匹配的情况下,那么匹配程度最高的逐字匹配指令会被使用。

Location规则匹配优先级总结如下:

(location =) > (location 完整路径) > (location ^~ 路径) > (location ~|~* 正则顺序) > (location 部分起始路径) > (location  /)

匹配优先级顺序

1、location先进行"="或"完整路径"的精确匹配,如:location =/www/index.html

2、^~字符串匹配,如: location ^~ /flv/

3、~和~正则匹配,如: location ~ .(html|css)$

4、目录或部分起始路径匹配,如: location /image/

5、默认匹配 location /

官方案例:

location = / {
    [ configuration A ]       --- 优先级最高 1 精确匹配
}

location / {                  --- 所有匹配都不满足时候,优先级最低,匹配默认location 5
    [ configuration B ]
}

location /documents/ {        --- 根据资源目录进行匹配         4 目录或部分路径匹配
    [ configuration C ]
}

location ^~ /images/ {        --- 优先匹配 2  字符串匹配
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {  --- 不区分大小写匹配网站资源  3 正则匹配
    [ configuration E ]
}

三、location匹配的实战案例

echo-nginx-module模块下载地址

https://github.com/openresty/echo-nginx-module/archive/v0.58.tar.gz

请自行添加echo模块

 listen    80;
 server_name abc.com;
 }

“=” 精确匹配

•内容要同表达式完全一致才匹配成功

例:

location = / {
.....
}
# 只匹配http://abc.com
# http://abc.com [匹配成功]
# http://abc.com/index [匹配失败]

“~”,大小写敏感

例·:

location ~ /Example/ {
.....
}
#http://abc.com/Example/ [匹配成功]
#http://abc.com/example/ [匹配失败]

“~*”,大小写忽略

例:

location ~* /Example/ {
.....
}
# 则会忽略 uri 部分的大小写
#http://abc.com/test/Example/ [匹配成功]
#http://abc.com/example/ [匹配成功]

“^~”,只匹配以 uri 开头

例:

location ^~ /index/ {
.....
}
#以 /index/ 开头的请求,都会匹配上
#http://abc.com/index/index.page  [匹配成功]
#http://abc.com/error/error.page [匹配失败]

“@”,nginx内部跳转

location /index/ {
error_page 404 @index_error;
}
location @index_error {
.....
}
#以 /index/ 开头的请求,如果链接的状态为 404。则会匹配到 @index_error 这条规则上。

不加任何规则

•不加任何规则则时,默认是大小写敏感,前缀匹配,相当于加了“~”与“^~”

•只有 / 表示匹配所有uri

location /index/ {
......
}
#http://abc.com/index  [匹配成功]
#http://abc.com/index/index.page  [匹配成功]
#http://abc.com/test/index  [匹配失败]``
#http://abc.com/Index  [匹配失败]

匹配到所有uri

location / {
......
}

location匹配的是nginx的哪个变量?

$request_uri

location的匹配种类有哪些?

格式 location [ 空格 | = | ~ | ~* |^~|!~ | !~* ] /uri/ {}

=开头表示精确匹配

^~ 开头,注意这不是一个正则表达式--它的目的是优于正则表达式的匹配。如果该location是最佳匹配,则不再进行正则表达式检测。

~ 开头表示区分大小写的正则匹配;

~* 开头表示不区分大小写的正则匹配

/ 通用匹配, 如果没有其它匹配,任何请求都会匹配到

!~ && !~*:表示区分大小写不匹配的正则和不区分大小写的不匹配的正则

location搜索顺序

顺序 or优先级:(location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (/)

1.首先匹配=

2.其次匹配^~

3.再其次按照配置文件的顺序进行正则匹配

4.最后是交给/进行通用匹配

注意: 当有匹配成功时,立刻停止匹配,按照当前匹配规则处理请求

特别注意: 字符串匹配优先搜索,但是只是记录下最长的匹配 ( 如果 ^~ 是最长的匹配,则会直接命中,停止搜索正则 ),然后继续搜索正则匹配,如果有正则匹配,则命中正则匹配,如果没有正则匹配,则命中最长的字符串匹配.

举例说明

( 这里使用了 echo-nginx-module 模块,方便做输出测试 )

精确匹配

location = /images/test.png {
  echo 'config1';
}
 
location  /images/test.png {
  echo 'config2';
}
 
location \/images\/test\.png$ {
  echo 'config3';
}

如果此时请求 http://127.0.0.1/images/test.png 会输出什么呢?

输出 config1, 毋容置疑,精确匹配优先级最高!

精确匹配的特殊情况

location = / {
  index index.html;
}
 
location / {
  echo 'config2';
}

此时是输入http://127.0.0.1 会输出什么呢?

是输出 config2, 怎么精确匹配的优先级不灵了呢?

是这样的,精确匹配还是起作用了,请求目录(非具体文件),nginx会将请求内部定向到index文件, 既此时真正的请求是http://127.0.0.1/index.html, 这是 config2则被命中!

所以精确匹配不要用来匹配 /

字符串搜索与正则搜

location /images/test.png {
echo 'config1';
}
 
location ^~ /images/ {
echo 'config2';
}
 
location ~ \/images\/test\.png$ {
echo 'config3';
}
 
location ~ \/images\/ {
echo 'config4';
}

如果此时请求 http://127.0.0.1/images/test.png 会输出什么呢?

当然是 config3,正则命中(虽然 config1 为最长匹配的字符串,此时只做记录,后面还要搜索正则匹配,则config3正则匹配命中),仔细观察可以发现config4也被匹配成功了,但是正则的匹配顺序是按照location的定义顺序匹配的,所以config3命中.

字符串匹配优先级的提升( ^~ )

location /images/ {
echo 'config1';
}
 
location ^~ /images/test.png {
echo 'config2';
}
 
location ~ /images/test\.png$ {
echo 'config3';
}
 
location ~ \/images\/ {
echo 'config4';
}

如果此时请求 http://127.0.0.1/images/test.png 会输出什么呢?

当然是config2, 首部匹配命中(因为字符串匹配是优先搜索的,此时发现config2 为最长的字符串匹配且为^~匹配方式,所以停止搜索正则,直接命中!)

 

posted @ 2020-09-08 14:52  yaowx  阅读(567)  评论(0编辑  收藏  举报