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    理解源於此


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM