Nginx 实践(二):配置之匹配规则

nginx通过server块中 location 配置用以匹配不同url访问:location配置方式主要包括 精准匹配普通匹配正则匹配

location = expression 精准匹配
location expression 普通匹配
location ^~ expression 普通匹配
location ~ regex 正则匹配(区分大小写)
location ~* regex 正则匹配(不区分大小写)
精准匹配要求uri与表达式(expression)完全匹配。
普通匹配要求uri与表达式满足前缀匹配。
正则匹配要求uri与正则表达式匹配。

匹配顺序

1.精准匹配2.普通匹配3.正则匹配

匹配顺序细节

1、首先与精准匹配进行匹配,如能匹配,则进行转发。如未能匹配成功,则进行普通匹配(^~)。
2、nginx将uri和所有^~类型的普通匹配规则进行匹配,如多个规则均命中,则选择最长匹配。匹配成功后,进行转发。否则,则进行正则匹配。
3、正则匹配与顺序有关,按编写顺序进行匹配,一旦匹配成功,则转发请求并停止匹配。匹配不成功,则进行普通匹配(location expression )
4、进行普通匹配(location expression),匹配成功则转发,不成功则返回错误码。

php匹配

原理是nginx 转发请求到php容器,含.php(.*)$ 结尾的转发php容器。静态文件需匹配别的location,如:/var/www/html/htdocs

server {
    listen       80;
    server_name  localhost;
    error_page   500 502 503 504  /50x.html;
    error_log  /var/www/html/access.log;
    access_log /var/www/html/error.log;


    location / {
        root   /var/www/html/htdocs; #这个目录是nginx中项目的根目录指到public
        index index.php index.html index.htm;

	#隐藏index.php
        if (!-e $request_filename){
             rewrite ^(.*)$ /index.php?s=$1 last; break;
        }
    }

    location ~ \.php(.*)$ {
	fastcgi_pass  php:9000;
	fastcgi_index index.php;
	include        fastcgi_params;
            
        #pathinfo 模式
        fastcgi_split_path_info  ^((?U).+\.php)(/?.+)$;
        fastcgi_param  SCRIPT_FILENAME  /var/www/html/htdocs/$fastcgi_script_name;
        fastcgi_param  PATH_INFO  $1;
        fastcgi_param  PATH_TRANSLATED  /var/www/htm1/htdocs/$fastcgi_path_info;

    }
}

配置详情

nginx 监听端口,日志存储路径

   listen       80;
    server_name  localhost;
    error_page   500 502 503 504  /50x.html;
    error_log  /var/www/html/access.log;
    access_log /var/www/html/error.log;

静态图片请求,,隐藏index.php路径

  location / {
        root   /var/www/html/htdocs; #这个目录是nginx中项目的根目录指到public
        index index.php index.html index.htm;

	#隐藏index.php
        if (!-e $request_filename){
             rewrite ^(.*)$ /index.php?s=$1 last; break;
        }
    }

请求含.php的路径,转发到php

  location ~ \.php(.*)$ {
	fastcgi_pass  php:9000;
	fastcgi_index index.php;
	include        fastcgi_params;
            
        #pathinfo 模式
        fastcgi_split_path_info  ^((?U).+\.php)(/?.+)$;
        fastcgi_param  SCRIPT_FILENAME  /var/www/html/htdocs/$fastcgi_script_name;
        fastcgi_param  PATH_INFO  $1;
        fastcgi_param  PATH_TRANSLATED  /var/www/htm1/htdocs/$fastcgi_path_info;

    }

一、概述
nginx官方文档给出location语法如下:

1
location [=||*|^~] uri { … }
其中,方括号中的四种标识符是可选项,用来改变请求字符串和uri的匹配方式。uri是待匹配的请求字符串,可以是不包含正则的字符串,这种模式被称为“标准的uri";也可以包含正则,这种模式被称为"正则uri",如下:

1
2
location ~ ..(php|php5)?$ {
}
二、四种可选的标识符
标识符 描述
= 精确匹配;用于标准uri前,要求请求字符串和uri严格匹配。如果匹配成功,就停止匹配,立即执行该location里面的请求。
~ 正则匹配;用于正则uri前,表示uri里面包含正则,并且区分大小写。
~
正则匹配;用于正则uri前,表示uri里面包含正则,不区分大小写。
^~ 非正则匹配;用于标准uri前,nginx服务器匹配到前缀最多的uri后就结束,该模式匹配成功后,不会使用正则匹配。
无 普通匹配(最长字符匹配);与location顺序无关,是按照匹配的长短来取匹配结果。若完全匹配,就停止匹配。
备注:

1、如果uri里面包含正则表达式,就必须使用*标识符;

2、针对*匹配标识符,可以在前面加上!来取反,如下:

!~ 表示正则不匹配,区分大小写。

!~* 表示正则不匹配,不区分大小写。

2.1 “=”精准匹配案例

1
2
3
location = /login {

精确匹配 /login ,匹配成功后,立即结束

}
2.2 “~”区分大小写正则匹配案例

1
2
3
location ~ /images/ {

正则匹配,区分大小写,匹配成功后,立即结束

}
2.3 “~*”不区分大小写正则匹配案例

1
2
3
location ~* /images/ {

正则匹配,不区分大小写,匹配成功后,立即结束

}
2.4 “^~” 不进行正则匹配的标准匹配

1
2
3
location ^~ /images/ {

匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。

}

2.5 普通匹配(最长字符匹配)

1
2
3
4
location /blog/ {

与location顺序无关

若完全匹配成功,就不在继续匹配,否则还会进行正则匹配

}
三、location匹配顺序
在没有标识符的请求下,匹配规则如下:

1、nginx服务器首先在server块的多个location块中搜索是否有标准的uri和请求字符串匹配。如果有多个标准uri可以匹配,就匹配其中匹配度最高的一个location。

2、然后,nginx在使用location块中,正则uri和请求字符串,进行匹配。如果正则匹配成功,则结束匹配,并使用这个location处理请求;如果正则匹配失败,则使用标准uri中,匹配度最高的location。

备注:

1、如果有精确匹配,会先进行精确匹配,匹配成功,立刻返回结果。

2、普通匹配与顺序无关,因为按照匹配的长短来取匹配结果。

3、正则匹配与顺序有关,因为是从上往下匹配。(首先匹配,就结束解析过程)

4、在location中,有一种统配的location,所有的请求,都可以匹配,如下:

1
2
3
4
location / {

因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求

但是正则和最长字符串会优先匹配

}
结合标识符,匹配顺序如下:

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

(精确匹配)> (最长字符串匹配,但完全匹配) >(非正则匹配)>(正则匹配)>(最长字符串匹配,不完全匹配)>(location通配)

五、案例
假设,现有如下一些规则:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
location = / {
//精确匹配/ ,主机名后面不能带任何字符串
echo "规则A";
}

location = /login {
//精确匹配 /login 开头的地址,匹配符合以后,不在继续往下搜索
echo "规则B";
}

location ^~ /blog/ {
//非正则匹配,匹配/blog/后,停止往下搜索正则,采用这一条
echo "规则C";
}

location ~ .(gif|jpg|png|js|css)$ {
//区分大小写的正则匹配 若匹配成功,停止往下搜索正则,采用这一条
echo "规则D";
}

location ~* .png$ {
//区分大小写的正则匹配 ,停止往下搜索正则,采用这一条
echo "规则E";
}

location / {
//因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
//如果没任何规则匹配上,就采用这条规则
echo "规则F";
}

location /blog/detail {
//最长字符串匹配,若完全匹配成功,就不在继续匹配,否则还会进行正则匹配
echo "规则G";
}

location /images {
//最长字符串匹配,同上
echo "规则Y";
}

location ^~ /static/files {
//非正则匹配,若匹配成功,就不在继续匹配
echo "规则X";

参考链接

http://www.findme.wang/blog/detail/id/495.html

posted @ 2020-10-26 09:50  鲁哒哒  阅读(978)  评论(0编辑  收藏  举报