1.正则表达式和分组
由于Nginx配置文件中经常出现正则表达式,因此本章节专门对常见的正则表达式进行简单介绍。
[1] 开始与结束
java
^表示匹配输入字符串的开始
$表示匹配输入字符串的结束
[2] 匹配次数
shell
?表示匹配0次或者1次
+表示匹配1次或多次
*表示匹配0从或多次
{n}匹配n次,{n,}至少匹配n次,{n,m} 匹配n至m次
[3] 匹配字符
shell
\符号用于转义
.匹配除\n之外的任意字符
[xyz]表示匹配xyz中任意一个字符
[a-z]表示匹配任意小写字母;[^a-z]取反,表示匹配除小写字母之外的任意字符;
[A-Z]表示匹配任意大写字母;[a-zA-Z]匹配任意字母;
[0-9]表示匹配任意数字, 等价于\d; [^0-9]表示匹配任意数字, 等价于\D
\s匹配任何空白字符;\S匹配任何非空白字符;
x|y 表示匹配x或y
[4] 分组
shell
rewrite ^/group/(.*)$ /index.php?param=$1;
rewrite表示地址重写,将匹配正则表达式^/group/(.*)$
的url地址重写为/index.php?param=$1
.
如 url为/group/abc123
将修改为/index.php?param=abc123
.
基于前述正则表达式的介绍,对^/group/(.*)$
进行解析:
^/group/
表示匹配以/group/开头的url; (.*)是一个捕获组,表示捕获任意字符;整体看来,表示匹配任意以/group/开头的url,且将/group/后面的部分捕获,后续可以使用$1对其进行提取。
再给出一个案例:
shell
rewrite ^/group/(\d{4})/(\d{2})/?$ /index.php?year=$1&month=$2;
当url地址为/group/2024/03/
或者/group/2024/03
时,地址重写为/index.php?year=2024&month=03
.
对这段表达式进行解析:
^/group/表示匹配以/group/开头的url; (\d{4})和(\d{2})是捕获组,分别捕获4位数字和2位数字;/? 表示/可以匹配0次或者1次,即url是否以/结尾都可以; 整体来看,正则表达式匹配以/group/开头,紧跟4位数字,然后是分隔符,然后紧跟2位数字,可以以/结尾或者不带/. 并且将4位数字\d{4}提取为1, 将2位数字\\d{2}提取为2.
2.servername优先级
2.1 servername介绍
servername配置在server块中。当客户端向Nginx服务器发送请求时,Nginx会根据请求的Host头字段 与server_name进行匹配,以确定将请求转发到哪个server块进行处理。
servername可以使用ip或者域名方式进行,一般配置为域名,如:
shell
server_name localhost;
server_name 127.0.0.1;
也可以配置多个域名:
shell
server_name localhost transgpt env124;
2.2 servername配置方式
servername配置方式有以下4种:
[1] 完全匹配
shell
server_name env124;
[2] 左通配符匹配
以*开头的匹配方式
shell
server_name *124;
[3] 右通配符匹配
以*结尾的匹配方式
shell
server_name env*;
[4] 正则表达式匹配
shell
server_name ~^env\d{3}$;
优先级顺序为:完全匹配>左通配符匹配>右通配符匹配>正则表达式匹配.
3.3 默认匹配
当Nginx收到来自客户端的请求时,会根据端口缩小候选的server块范围,然后根据server_name进行匹配:
1\] 当存在多个匹配server块时,会根据1.2中提到的优先级进行匹配,选择优先级最高的第一个server块处理; \[2\] 当仅存在一个匹配的server块时,由该server块处理; \[3\] 当没有匹配的server块时,如果有默认块,使用默认块处理;如果没有默认块,则使用候选中的第一个server块。 ## 3.url类型和优先级 location块的语法格式为: ```shell location [ = | ^~ | ~ | ~* | 空 | / ] uri { #匹配后的处理逻辑,proxy_pass,root/alias/index等; } ``` location关键字和url之间有6种类型的匹配规则, 按优先级排序依次为: **\[1\] = 完全匹配** 请求路径必须与location的url完全匹配(大小写一致、斜线一致) ```shell server { listen 8888; server_name localhost; location = /test.html { return 200 "--Your are enter [http://localhost:8888/test.html]"; } } ``` 配置为/test.html时,只能以/test.html去请求,如下所示: ```shell [root@host44 conf]# curl http://localhost:8888/test.html --Your are enter [http://localhost:8888/test.html]-- ``` 其他(如下所示场景)则不能匹配: ```shell http://localhost:8888/test.html/ http://localhost:8888/test.htmla http://localhost:8888/Test.html http://localhost:8888/ ``` **\[2\] \^\~ 前缀匹配** > 说明:为理解方便,以下介绍匹配规则时,省去域名和端口。 ```shell location ~ /test { } ``` 匹配以/test开头的所有url, 如下所示: ```shell /test /test/ /test/abc /testabc ``` 注意:前缀匹配区分大小写。 当有多个前缀匹配满足时,有一个最大字符串匹配规则,即匹配字符串长度大的优先。 **\[3\] \~ 正则表达式匹配, 区分大小写** > 正则表达式语法可以参考"正则表达式"章节内容。 ```shell location ~ ^/query/.*$ { return 200 "query success"; } ``` 此时,正则表达式`^/query/.*$`表示所有以/query/开头的url. **\[4\] \~* 正则表达式匹配, 不区分大小写*\* 与\[3\]相似,区别在于不区分大小写。 ```shell #只能匹配/query/开头的url location ~ ^/query/.*$ { return 200 "query success"; } #可以匹配/QUerY/开头的url location ~* ^/query/.*$ { return 200 "query success"; } ``` **\[5\] 空** 与\^\~类似属于前缀匹配,但优先级低于正则表达式,最大字符串匹配规则仍然适应。 ```shell location ~ /test { } ``` 匹配以/test开头的所有url, 如下所示: ```shell /test /test/ /test/abc /testabc ``` **\[6\] / 通用匹配** 匹配所有请求,一般作为默认访问-访问网站首页,放在配置的最后。 ```shell location / { root /usr/local/nginx/conf/html/; index index.html; } ``` 除此之外,还有一种定义方式,使用@开头命名的location。该类型的location块不会参与url匹配, 仅用于nginx内部使用, 如try_files、errorpage, 案例如下所示: ```shell server { server_name localhost; listen 8001; location /query { try_files index.htm index.html @custom_404; } location /set { error_page 404 @index_error; } location @custom_404{ return 200 "Custom 404 page not found"; } } ``` 测试结果如下所示: ```shell [root@124 conf]# curl http://localhost:8001/queryxxx Custom 404 page not found [root@124 conf]# curl http://localhost:8001/setxxx Custom 404 page not found ```