八、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内部重定向的变量。 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 / {
......
}
$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 为最长的字符串匹配且为^~匹配方式,所以停止搜索正则,直接命中!)