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";