1. 程式人生 > 其它 >Nginx Location路由規則配置

Nginx Location路由規則配置

介紹

location路由匹配發生在HTTP請求處理的find-config配置查詢階段,主要功能是:根據請求的URI地址匹配location路由表示式,如果匹配成功,就執行location後面的上下文配置塊。

location 4中配置

語法格式

location [=|~|~*|^~] 模式字串 {
	...
}

按照匹配的符號不同,location路由匹配主要分成精準匹配、普通匹配、正則匹配、預設根路徑匹配。

1. 精準匹配

如果請求URI和精準匹配的模式字串/lua完全相同,那麼精準匹配通過。前面加上一個 = 即可,如 loction = /lua/
在所有的匹配型別中,精準匹配的優先順序最高。

2. 普通匹配

普通匹配的符號標記為“^~”

location ^~ /lua {
	echo "hit location: ^~ /lua";
}

普通匹配屬於字串字首匹配,詳細來說:如果請求路徑URI頭部匹配到location的模式字串,那麼匹配成功。如果匹配到多個字首,那麼最長模式匹配優先。
普通匹配是字首匹配,也是Nginx預設的匹配型別。也就是說,型別符號“^~”可以省略,如果location沒有任何匹配型別,就為普通的字首匹配。

# 不帶型別符號,預設為普通匹配
location /demo {
 echo "hit location: /demo ";
}
# 帶“^~”符號,普通匹配
location ^~ /demo {
 echo "hit location: ^~ /demo";
}

這兩種效果相同

3. 正則匹配

正則匹配的型別按照型別符號的不同可以細分為以下4種
(1)~:標準正則匹配,區分字母大小寫,進行正則表示式測試,若測試成功,則匹配成功。
(2)~:標準正則匹配,不區分字母大小寫,進行正則表示式測試,若測試成功,則匹配成功。
(3)!~:反向正則匹配,區分字母大小寫,進行正則表示式測試,若測試不成功,則匹配成功。
(4)!~
:反向正則匹配,不區分字母大小寫,進行正則表示式測試,若測試不成功,則匹配成功。

#正則匹配
 location ~*hello\.(asp|php)$ {
 	echo "正則匹配: hello.(asp|php)$ ";
 }

注意:
如果配置檔案中存在多個正則匹配location,那麼它們之間的規則是順序優先的,只要匹配到第一個正則型別的location,就停止後面的正則型別的location測試。

4. 預設根路徑匹配

根路徑的路徑規則就是使用單個“/”符號,示例如下:

location / {
   echo "預設根路徑匹配: /";
}

不能匹配到其他的location,只能匹配到“/”根路徑
表面看上去,location/{...}根路徑匹配非常類似普通匹配,但實際上該規則自成一類,雖然只有唯一的一個路徑,但是此類規則優先順序是最低的。

總結:

  1. 型別之間的優先順序:精準匹配>普通匹配>正則匹配>“/”預設根路徑匹配。
  2. 普通匹配同類型location之間的優先順序為最長字首優先。普通匹配的優先順序與location在配置檔案中所處的先後順序無關,而與匹配到的字首長度有關。
  3. 正則匹配同類型location之間的優先順序為順序優先。只要匹配到第一個正則規則的location,就停止後面的正則規則的測試。正則匹配與location規則定義在配置檔案中的先後順序強相關。

常用的location路由配置

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

表示在請求URI匹配到“/”根路由規則時,首先Nginx會在html目錄下查詢index.html檔案,如果沒有找到,就查詢index.htm檔案,將找到的檔案內容返回給客戶端。
“/”根路由規則也可以路由到一個訪問很頻繁的上游服務,比如Spring Cloud微服務架構中的服務閘道器:

location / {
   proxy_pass http://127.0.0.1:7799/;
}

注意:此處proxy_pass值後面有沒有這個斜槓,很重要;
示例說明:

location /user/ {
   proxy_pass http://127.0.0.1:7799/;
}

上面示例,會將請求轉發到 http://127.0.0.1:7799/xxxxx
後面有斜槓相當於沒有斜槓時,對地址進行了重寫,

location ^~/user/ {
        proxy_set_header Host $host;
        proxy_set_header  X-Real-IP        $remote_addr;
        proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header X-NginX-Proxy true;

        rewrite ^/user/(.*)$ /$1 break;
        proxy_pass http://127.0.0.1:7799;
    }

注意:
proxy_set_header可以在三處地方使用,分別是http, server, location, 但是繼承關係在官方文件明確說明了,本層如果沒有定義任何proxy_set_header,就從上層繼承,如果已經定義了,就不會從上層進行繼承;

此處proxy_pass後面沒有/, 進行了rewrite重寫,效果會將請求轉發到 http://127.0.0.1:7799/xxxxx

# http://grandpic.oss-cn-shanghai.aliyuncs.com/illegal/20211231/34020000001320001030/10.210.103.175_01_20211231164609541_TIMING.jpg
# 經過改代理後,圖片就變為了
# http://grandpic.oss-cn-shanghai.aliyuncs.com/pics/illegal/20211231/34020000001320001030/10.210.103.175_01_20211231164609541_TIMING.jpg
	location ^~ /illegal/ {
		proxy_pass https://zhst-obs-01.obs.cn-southwest-217.tianfugongyuancheng.com/pics/illegal/;
	}

location /user/ {
   proxy_pass http://127.0.0.1:7799;
}

上面示例,會將請求轉發到 http://127.0.0.1:7799/user/xxxxx
^~/user/表示匹配字首是user的請求,proxy_pass的結尾有/, 則會把/user/*後面的路徑直接拼接到後面,即移除user.

root /www/resources/static/;
 #字首匹配
location ^~ /static/ {
 root /www/resources/;
}

所有匹配/static/...規則的靜態資源請求(如/static/img/1.png)都將路由到root指令所配置的檔案目錄/www/resources/static/下對應的某個檔案(如/www/resources/static/img/1.png),root最後面跟上/,和proxy_pass的效果不同。

# 如果 url 含有 .  , 並且 不以 do 或 action 結尾,則匹配成功。
location ~ .*\.(?!(do|action)$) {
	root /demo/code/webroot;
}

參考:

[1] https://www.toutiao.com/i6975472488293745159/
[2] https://www.cnblogs.com/woshimrf/p/nginx-proxy-rewrite-url.html
[3] https://blog.csdn.net/qq_34817440/article/details/100162354