zoukankan      html  css  js  c++  java
  • nginx的location优先级

    问题:nginx设置了expires,但是不生效。有些细节真的是不去用它,不出问题真的发现不了什么
     
    nginx的配置文件如下:
     
    server {
        listen 80;
        server_name aa.lile.com;
        root  /data/lile;
    
        index index.html index.htm index.php;
    
        charset utf-8;
    
        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }
    
        access_log on;
        access_log /var/log/lile.com;
        sendfile off;
    
        location ~ \.(gif|jpg|png|css|js|swf|plist|xml)$ {
            expires 90d;
        }
    
        location / {
            add_header Access-Control-Allow-Origin *;
        }
    }
    设置了:
    location ~ \.(gif|jpg|png|css|js|swf|plist|xml)$ 
    {
            expires 90d;     
     

    但是去访问的时候,返回的结果为:

    并没有返回过期时间,猜测这是因为location这里的匹配是有优先级的

    location的相关知识点:
     
    模块:ngx_http_core_module
     
    location的语法结构:
    location [ = | ~ | ~* | ^~ ] uri { ...... }
     
    理解及测试:
    location = /uri                   =表示精准匹配,只要完全匹配上才能生效。
    location /uri                     不带任何修饰符,也表示前缀匹配,但是在正则匹配之后
    location /                          通用匹配,任何未匹配到其他location的请求都会匹配到
    location ^~ /uri                 开头对URL路径进行前缀匹配,并且在正则之前。一旦匹配到最长匹配,则不再查找其他匹配项
    location ~ pattern            开头表示区分大小写的正则匹配
    location ~* pattern           开头表示不区分大小写的正则匹配,如果有多个location匹配,则选择匹配最长的那个
     
     
    精准匹配: 相等(=)
    字符串匹配:字符串匹配(空格)、匹配开头(^~)
    正则匹配: 区分大小写匹配(~)、不区分大小写匹配(~*)、区分大小写不匹配(!~)、不区分大小写不匹配(!~*)
     
    优先级:
    精准匹配  > 字符串匹配(长 > 短,^~匹配是最长匹配则停止匹配) > 正则匹配(先后顺序)
     
    精准匹配只能匹配一个
    字符串匹配使用匹配最长的为匹配结果
    正则匹配按照location定义的顺序进行匹配,先定义具有最高优先级
     
    注:字符串匹配优先搜索,但是只是记录下最长的匹配(如果^~是最长匹配,则会直接命中,停止搜索正则),然后继续正则匹配,如果有正则匹配,则命中正则匹配,如果没有正则匹配,则命中最长的字符串匹配
     
    自己总结匹配顺序:
    1)精准匹配,若成功,则停止后面的步骤,若没有,继续下面的步骤
    2)普通匹配(若有多个匹配项匹配成功,那么选择匹配长的并记录,并继续下面的匹配步骤,若这个匹配长的记录刚好是^~,那么就不再进行下面的步骤
    3)正则表达式匹配(若匹配到了,那么返回正则表达式匹配到的;若有多个正则匹配到了,那么选择配置文件正则在前面的那一个,若没有,那么返回第二步中,匹配最长的那个)

    例1:

    server {
        listen 80;
        server_name aaaa.lile.com;
        root  /data/lile;
    
        index index.html index.htm index.php;
    
        charset utf-8;
    
        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }
    
        access_log on;
        access_log /var/log/lile.com;
        sendfile off;
    
        location = /images/test.png {
            return 001;
        }
    
        location  /images/test.png {
            return 002;
        }
        location /images/test.png$ {
            return 003;
        }
    
        location = / {
            index index.html;
        }
    
        location / {
            return 005;
        }
    
    }

    测试1:精准匹配

    测试2:

    这个按理说是应该要精准匹配到index.html,但是匹配到了返回005的这里,这是因为http://aaaa.lile.com会跳转到http://aaaa.lile.com/index.com

     

    如果把上面的
        location = / {                                                                                 location = / {
            index index.html;                    =======》 改为                               return 004;
        }                                                                                                    }
     
    那么再测试访问http://aaaa.lile.com的时候就会返回004
     

    例2:

    server {
        listen 80;
        server_name aaaaa.lile.com;
        root  /data/lile;
    
        index index.html index.htm index.php;
    
        charset utf-8;
    
        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }
    
        access_log on;
        access_log /var/log/lile.com;
        sendfile off;
    
        location /images/test.png {
            return 001;
        }
    
        location ^~ /images/ {
            return 002;
        }
    
        location ~ /images/test.png$ {
            return 003;
        }
    
        location ~ /images/ {
            return 004;
        }
    
    }

    测试1:

    当匹配到001时,只是做记录,后面还要正则匹配,正则匹配到了003,若在正则匹配的时候没有匹配到,那么就会返回001

    例3:

    server {
        listen 80;
        server_name aaaaa.lile.com;
        root  /data/lile;
    
        index index.html index.htm index.php;
    
        charset utf-8;
    
        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }
    
        access_log on;
        access_log /var/log/lile.com;
        sendfile off;
    
        location /images/ {
            return 001;
        }
    
        location ^~ /images/test.png {
            return 002;
        }
    
        location ~ /images/test.png$ {
            return 003;
        }
    
        location ~ /images/ {
            return 004;
        }
    
    }

    测试1:

     例4: 

    server {
        listen 80;
        server_name aa.lile.com;
    
        index index.html index.htm index.php;
    
        charset utf-8;
    
        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }
    
        access_log on;
        access_log /var/log/lile.com;
        sendfile off;
    
        location ~* .jpg$ {
            return 3;
        }
    
        location ^~ /a {
            return 4;
        }
    
        location /a/1.jpg {
            return 5;
        }
    
        location / {
            return 7;
        }
    
    }

    测试1:

     

    为什么不一样?

    这里一直理解错了,并不是只要一匹配到了^~就停止,而是当匹配到^~,并且是^~是最长匹配的时候才停止,所以过程如下:
     
    /a/1.jpg的匹配过程为:
    1)location /a/1.jpg
    2)location ^~ /a         这里的^~并不是最长匹配,所以继续下面的步骤
    3)location ~* .jpg$   匹配成功,所以返回003
     
    /a/2.jpg的匹配过程为:
    1)location ^~ /a      因为它直接匹配到这里,并且是最长的所以停止匹配,返回004

    匹配流程图:

    回到最上面的出现的问题,就能知道为什么了。

    server {
        listen 80;
        server_name aa.lile.com;
        root  /data/lile;
    
        index index.html index.htm index.php;
    
        charset utf-8;
    
        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }
    
        access_log on;
        access_log /var/log/lile.com;
        sendfile off;
    
        location ~ \.(gif|jpg|png|css|js|swf|plist|xml)$ {
            return 111;
            expires 90d;
        }
    
        location / {
            return 222;
            add_header Access-Control-Allow-Origin *;
        }
    }

    测试一下:按理说应该先匹配上面的那个返回111,但是结果却不一样,返回的是222;这是为什么呢

    经过不断的看,终于发现了这个符号是错的,不是英文下的反斜线,而是全角符号的反斜线

     改过来,重新reload一下nginx的配置文件,现在就返回正常了:

    相关博文:

    https://www.2cto.com/kf/201703/616033.html    理解源于此

  • 相关阅读:
    如果你想开发一个应用(1-17)
    如果你想开发一个应用(1-16)
    如果你想开发一个应用(1-15)
    0079 Ehcache 3.x应用入门及通过JCache与Spring整合
    0078 Java与MySQL时间戳传递/存储/协调问题--userLegacyDatetimeCode--userTimezone--serverTimezone
    0077 web.xml中配置Spring MVC时,Servlet-name上报Servlet should have a mapping的错误
    0076 判断回文串
    0075 字符串的反转
    0074 几道面试题
    0073 javacTask: 源发行版 1.8 需要目标发行版 1.8
  • 原文地址:https://www.cnblogs.com/lemon-le/p/8215320.html
Copyright © 2011-2022 走看看