1. 程式人生 > 實用技巧 >nginx服務location區段匹配規則詳解

nginx服務location區段匹配規則詳解

目錄

1. location區段

通過指定模式來與客戶端請求的URI相匹配

//功能:允許根據使用者請求的URI來匹配定義的各location,匹配到時,此請求將被相應的location配置塊中的配置所處理,例如做訪問控制等功能

//語法:location [ 修飾符 ] pattern {......}

詳細語法可以檢視nginx官方文件

在配置檔案裡新加一個location,新增web資訊

.............
        location / {
            root   html;
            index  index.php index.html index.htm;
        }

        location /zabbix {
            root   /opt/myweb;      //定義存放目錄
            index  index.html;
        }
.............

如果是直接在 /opt/myweb下建立的話,訪問會報錯,如下圖所示

這時需要注意了, 此時的順序應該/opt/myweb/zabbix/index.html
所以此時應該先建立zabbix再建立index.html,之後nginx重讀檔案,再次訪問

剛才那種方式會顯得有些繁瑣,此時可以把root更改為alias

  ...........
  location /zabbix {
            alias   /opt/myweb;
            index  index.html;
        }
  ...........

此時訪問的順序是 /opt/myweb/index.html



因為要演示修飾符的效果,所以這裡nginx需要重新安裝一個echo模組

2. 安裝nginx-echo模組

//下載模組
[root@longnian ~]# wget https://github.com/openresty/echo-nginx-module/archive/v0.61.tar.gz

//解壓
[root@longnian ~]#  tar xf v0.61.tar.gz

//檢視原來的編譯引數
[root@longnian ~]# nginx -V
nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log

//重新編譯nginx
[root@node1 nginx-1.18.0]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --add-module=/root/echo-nginx-module-0.61
//在最後加上--add-module=/root/echo-nginx-module-0.61
[root@node1 nginx-1.18.0]# make

//將nginx安裝目錄中的nginx檔案備份
[root@longnian ~]# mv /usr/local/nginx/sbin/nginx /opt

//將我們重新編譯的nginx檔案複製到nginx安裝目錄中
[root@longnian ~]#nginx -s stop;cp nginx /usr/local/nginx/sbin/;nginx 
//上面這種方式,在檔案啟動的時候也能複製進去

//過載配置檔案
[root@longnian ~]# nginx -s reload

3. 講解匹配規則

常用修飾符說明:

修飾符 功能
= 精確匹配
~ 正則表示式模式匹配,區分大小寫
~* 正則表示式模式匹配,不區分大小寫
^~ 字首匹配,類似於無修飾符的行為,也是以指定模組<>開始,不同的是,如果模式匹配,那麼就停止搜尋其他模式了,不支援正則表示式
@ 定義命名location區段,這些區段客戶端不能訪問,只可以由內部產生的請求來訪問,如try_files或error_page等

沒有修飾符的情況下

//在配置檔案裡新增新的location
............
 location /abc {
            echo "沒有修飾符";
        }
............

//用curl來訪問驗證
[root@longnian ~]# curl http://192.168.159.144/abc
沒有修飾符
[root@longnian ~]# curl http://192.168.159.144/abc/
沒有修飾符
[root@longnian ~]# curl http://192.168.159.144/abc/haha
沒有修飾符
[root@longnian ~]# curl http://192.168.159.144/abcd
沒有修飾符
[root@longnian ~]# curl http://192.168.159.144/ab
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

通過驗證可以發現,只要開頭是abc的,後面無論接的什麼內容,都能匹配到。最後把abc修改為ab,結果就報錯了!
總結就是:

所有請求都可以匹配到,匹配到一個普通格式後,搜尋並未結束,而是暫存當前匹配的結果,並繼續搜尋正則匹配模式 ,匹配到正則就交給正則匹配處理,如果沒有匹配到正則就以暫存的結果為匹配結果

修飾符“=”:精準匹配

//在配置檔案裡新增新的location
............
location = /abc {
            echo "我只能被精準匹配到!";
        }
............

//用curl來訪問驗證
[root@longnian ~]# curl http://192.168.159.144/abc
我只能被精準匹配到!
[root@longnian ~]# curl http://192.168.159.144/abc/
沒有修飾符
[root@longnian ~]# curl http://192.168.159.144/abc/xixi
沒有修飾符
[root@longnian ~]# curl http://192.168.159.144/ab
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

通過驗證可以看出,/abc用了精準匹配之後,只有在匹配abc的時候才能訪問出來,其他任何情況都不能訪問到abc
總結就是:

嚴格匹配,只有完全相等才匹配成功,然後停止匹配,不然繼續匹配

修飾符“~”:正則表示式模式匹配,區分大小寫

//在配置檔案裡新增新的location
............
location ~ ^/abc$ {
            echo "我是區分大小寫的!";
        }

............

//用curl來訪問驗證
[root@longnian ~]# curl http://192.168.159.144/abc
我是區分大小寫的!
[root@longnian ~]# curl http://192.168.159.144/ABC
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
[root@longnian ~]# curl http://192.168.159.144/abc/
沒有修飾符

通過驗證可以看出,效果很明顯,加上了~,大寫的就不能訪問到!

修飾符“~*”:正則表示式模式匹配,不區分大小寫

//在配置檔案裡新增新的location
............
location ~* ^/abc$ {
            echo "我是不區分大小寫的!";
        }

............

//用curl來訪問驗證
[root@longnian ~]# curl http://192.168.159.144/abc
我是區分大小寫的!
[root@longnian ~]# curl http://192.168.159.144/ABC
我是不區分大小寫的!
[root@longnian ~]# curl http://192.168.159.144/abc/
沒有修飾符

通過驗證可以看出,效果很明顯,加上了~*,就不區分了大小寫
補充:

~ 和 ~* 實質上是同級的,優先順序取決於配置檔案書寫的先後順序,先寫的優先順序高

查詢順序和優先順序:由高到底依次為

  • 帶有=的精確匹配優先
  • 正則表示式按照他們在配置檔案中定義的順序
  • 帶有^~修飾符的,開頭匹配
  • 帶有*修飾符的,如果正則表示式與URI匹配
  • 沒有修飾符的精確匹配

要點總結:

  • location 的匹配順序是“先匹配普通,再匹配正則”
  • 普通匹配與配置書寫順序無關,因為按照匹配的長短來取匹配結果
  • 正則匹配與順序有關,因為是從上往下匹配。
  • 正則匹配項匹配規則,受配置檔案的前後順序影響,但普通匹配模式不會