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