Nginx的location规则
概念
可以通过配置location指令块,决定客户端发过来的请求URI是如何处理的;
语法:
Syntax: location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
Default: —
Context: server, location
Location 的配置可以有两种配置方法,可以在server指令块和location指令块中配置
- 修饰符+URI(资源路径)
- @+name:这种是内部跳转用到;
修饰符讲解:
=:精确匹配(必须全部都相等)
- 精确匹配,一般是匹配某个具体文件;
范例:
location = /haha {
allow 192.168.75.130;
deny all;
root /data/;
index index.html index.htm;
}
#匹配的uri是 192.168.75.130:/haha,这样就直接指定了路径
~:大小写敏感(正则表达式)
- 匹配的大小写敏感
- 使用的是正则表达式
范例
location ~ /haha {
allow 192.168.75.130;
deny all;
root /data/;
index index.html index.htm;
}
#这种请求相当于:
用户访问:192.168.75.130:/haha---->这个是可以访问到资源的
用户访问:192.168.75.130:/HAHA--->这个是无法获取到资源的;
~*:忽略大小写(正则表达式),
- 这里需要注意忽略大小写的意思是请求的字符大小写都是可以的
- 大事不会进行大小写转换,请求的大小写对应的文件必须存在;
- 大小写忽略,值得是uri部分的大小写忽略
范例:
location ~* /haha {
allow 192.168.75.130;
deny all;
root /data/;
index index.html index.htm;
}
#这个是忽略大小写的匹配
用户访问:192.168.75.130:/haha---->这个是可以访问到资源的;访问的是haha里面的资源
用户访问:192.168.75.130:/HAHA--->这个是也可以访问,但是访问的资源的HAHA里面的资源
^~:只需匹配uri部分
- 这里指的是进京匹配以uri开头的,匹配成功了之后,会停止搜索后面的正则表达式匹配;
示例:
location ^~ /haha {
allow 192.168.75.130;
deny all;
root /data/;
index index.html index.htm;
}
#匹配以/haha/目录开头的都能够匹配上;
用户匹配:192.168.75.130:/haha/liangjiawei.PNG-->可以匹配
用户匹配:192.168.75.130:/haha/liangjiawei.png-->也可以成功匹配
#这里需要注意的是:如果被^~这个规则匹配到的话, 其他的正则表达式就不会进行;
@:内部服务跳转
指定后缀的匹配
- 处理匹配以gif、jpg、jpeg结尾的文件
范例:
location ~* \.(gif|jpg|png|swf|flv)$ {
valid_referers none blocked *.liangjiawei.net;
root /data/html/;
if ($invalid_referer) {
return 403;
}
}
#这里只要是访问192.168.75.130:/dadas/dsjlfj/dsfj.jgp->匹配成功
#还是访问192.168.75.130:/img/liangjiawei.png-->都可以匹配成成
location的规则实验
这个实验是结合以上所有的修饰符进行讲解;
添加一个echo模块,可以简化操作;
#准备echo模块
[root@node1 src]# rz
[root@node1 src]# ls echo-nginx-module-0.61.tar.gz
echo-nginx-module-0.61.tar.gz
#解压模块并且改一个名字
[root@node1 src]# tar -xf echo-nginx-module-0.61.tar.gz
[root@node1 src]# mv echo-nginx-module-0.61 echo-nginx-module
#进入到nginx的源码目录进行预编译、编译、安装、升级
[root@node1 src]# cd nginx-1.17.10/
#查看原来的编译选项
[root@node1 nginx-1.17.10]# nginx -V
nginx version: nginx/1.17.10
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
configure arguments: --prefix=/usr/local/nginx
#重新预编译
#--add-module=注意这个echo模块的路径
[root@node1 nginx-1.17.10]# ./configure --prefix=/usr/local/nginx --add-module=../echo-nginx-module
#编译安装
[root@node1 nginx-1.17.10]# make && make install
#直接升级
[root@node1 nginx-1.17.10]# make upgrade
/usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
sleep 1
test -f /usr/local/nginx/logs/nginx.pid.oldbin
kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`
[root@node1 nginx-1.17.10]#
#再次查看一下nginx的编译参数
#已经添加了echo模块
[root@node1 nginx-1.17.10]# nginx -V
nginx version: nginx/1.17.10
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
configure arguments: --prefix=/usr/local/nginx --add-module=../echo-nginx-module
完成实验,修改nginx的配置文件
#修改配置文件
[root@node1 nginx-1.17.10]# cd /usr/local/nginx/
[root@node1 nginx]# vim conf/nginx.conf
#增加如下内容
......................
location / {
echo "这是默认的 $request_uri";
}
location ~* \.(jpg|png) {
echo "这是~* \.(jpg|png)";
}
location ~ \.(jpg|png) {
echo "这是大小写敏感的~ \.(jpg|png)";
}
location ^~ /haha/ {
echo "这是只要匹配上就停止的 ^~ /haha/";
}
location = /haha/liangjiawei.png {
echo "这是只要绝对相等的 = /haha/liangjiawei.png ";
}
.......
#修改好了之后,重载配置文件
[root@node1 nginx]# nginx -s reload
验证规则的优先级:
首先让客户请求
[root@node-130 nginx]# curl 192.168.75.131/haha/liangjiawei.png
这是只要绝对相等的 = /haha/liangjiawei.png
#这里可以发现,如果资源一致,直接匹配=号的规则
第一:取出uri:让客户端访问的是/haha/liangjiawei.pg
第二步:去掉location规则,查找有没有= /haha/liangjiawei.png的规则,有的话就停止匹配
[root@node-130 nginx]# curl 192.168.75.131/haha/liangjiawei.png
这是只要绝对相等的 = /haha/liangjiawei.png
#去到配置文件中,注释掉=的规则
[root@node1 nginx]# vim conf/nginx.conf
............
#location = /haha/liangjiawei.png {
# echo "这是只要绝对相等的 = /haha/liangjiawei.png ";
# }
#记得重启配置文件
[root@node1 nginx]# nginx -s reload
第三步:注释这=号的规则之后,再来访问一下,看看是是哪个规则可以匹配
#这里可以发现:如果=号规则没有了,那么nginx直接有^~匹配开头是的规则来取代
[root@node1 nginx]# curl 192.168.75.131/haha/liangjiawei.png
这是只要匹配上就停止的 ^~ /haha/
第四步:再把^~这个规则取消,再来查看一下
- 这里我们也可以发现,匹配的规则是忽略大小写的匹配规则出现在我们眼前
- 问题:我们命名指定png,为什么不是~规则出现?
[root@node1 nginx]# vim conf/nginx.conf
#location ^~ /haha/ {
# echo "这是只要匹配上就停止的 ^~ /haha/";
# }
#重载配置文件
#然后再次访问
[root@node1 nginx]# curl 192.168.75.131/haha/liangjiawei.png
这是~* \.(jpg|png)
为了解答上面的问题,我们查看一下nginx剩余的规则
- 发现~*这个规则是排在上面的;
- 总结就是同时正则的规则,可以安装配置文件中的先后进行匹配(从上往下的顺序)
[root@node1 nginx]# vim conf/nginx.conf
location / {
echo "这是默认的 $request_uri";
}
location ~* \.(jpg|png) {
echo "这是~* \.(jpg|png)";
}
location ~ \.(jpg|png) {
echo "这是大小写敏感的~ \.(jpg|png)";
}
..........
#调换一下位置再次验证
[root@node1 nginx]# vim conf/nginx.conf
location / {
echo "这是默认的 $request_uri";
}
location ~ \.(jpg|png) {
echo "这是大小写敏感的~ \.(jpg|png)";
}
location ~* \.(jpg|png) {
echo "这是~* \.(jpg|png)";
}
#验证是~这个规则出来
[root@node1 nginx]# nginx -s reload
[root@node1 nginx]# curl 192.168.75.131/haha/liangjiawei.png
这是大小写敏感的~ \.(jpg|png)
最后:把所有的规则都去掉
#修改配置文件
[root@node1 nginx]# vim conf/nginx.conf
........
location / {
echo "这是默认的 $request_uri";
}
#location ~ \.(jpg|png) {
# echo "这是大小写敏感的~ \.(jpg|png)";
# }
#location ~* \.(jpg|png) {
# echo "这是~* \.(jpg|png)";
# }
#location ^~ /haha/ {
# echo "这是只要匹配上就停止的 ^~ /haha/";
# }
#location = /haha/liangjiawei.png {
# echo "这是只要绝对相等的 = /haha/liangjiawei.png ";
#重载配置文件验证
[root@node1 nginx]# nginx -s reload
[root@node1 nginx]# curl 192.168.75.131/haha/liangjiawei.png
这是默认的 /haha/liangjiawei.png