location
以 = 開頭,表示精確匹配;如只匹配根目錄結尾的請求,後面不能帶任何字符串。
以^~ 開頭,表示uri以某個常規字符串開頭,如果匹配到,則不繼續往下匹配。不是正則匹配
以~ 開頭,表示區分大小寫的正則匹配;
以~* 開頭,表示不區分大小寫的正則匹配
以/ 開頭,通用匹配, 如果沒有其它匹配,任何請求都會匹配到
*注意 location xxx {} 其中xxx與括號之間很多時候需要空格,最好都加上
匹配順序:
(location =) > (location 完整路徑) > (location ^~ 路徑) > (location ~,~* 正則順序) > (location 部分起始路徑) > (/)
rewrite
rewrite只能放在 server{}, location{}, if{}中,並且只能對域名後的文件路徑起作用。
執行順序
- 執行server塊的rewrite指令
- 執行location匹配
- 執行選定的location中的rewrite指令
語法
rewrite regex replacement [flag];
flag
這兒分爲server級和location級,其中if可寫在server和location中,分別對應server級和location級。同級別中執行順序看書寫順序。
last : 不再執行同級rewrite,寫在location中重新循環server.
break : 不再執行同級rewrite,只往後匹配,如果在location中,會報404,因爲location中沒有嵌套location使其往繼續往下級匹配;
redirect : 返回302臨時重定向,地址欄會顯示跳轉後的地址
permanent : 返回301永久重定向,地址欄會顯示跳轉後的地址
當不寫flag時,再次循環同級匹配
if(condition)
當表達式只是一個變量時,如果值爲空或任何以0開頭的字符串都會當做false
直接比較變量和內容時,使用=或!=
~ 正則表達式匹配
~* 不區分大小寫的匹配
!~ 區分大小寫的不匹配
-f和!-f 用來判斷是否存在文件
-d和!-d 用來判斷是否存在目錄
-e和!-e 用來判斷是否存在文件或目錄
-x和!-x 用來判斷文件是否可執行
其他
調試
default_type application/json;
在locaiton中 return 200 '$uri xxx'
變量
set $a "1"
if ($a = "1") {
return 302
}
proxy_pass
proxy_pass http://127.0.0.1:8008/;
這裏只討論在location中的proxy_pass;
1、 location 使用非正則匹配
location /api {
# 1. proxy_pass http://127.0.0.1:8008/a;
# 2. proxy_pass http://127.0.0.1:8008;
}
- 1中 端口後面有"/" ,訪問/api/test → /a/test;(匹配剩餘的地址爲/test,再將地址拼接到代理地址中)
- 2中 端口後面沒有"/" ,訪問/api/test → /api/test
此處要注意,並不是uri最後是否有"/",是端口後面是否有"/"
2、location 使用正則匹配
location ~ /api/ {
proxy_pass http://127.0.0.1:8008;
}
- 端口後面不加/,可行。
- 端口後面加/,則必須使用變量(任何變量都行,讓其使用第3條規則)。因爲代理地址會自動加上匹配剩餘的uri,代理去正則匹配剩餘的uri會使地址亂套。
3、如果proxy_pass後面有變量,直接去的那個地址,跳出1 2條規則。
舉例
server {
listen 80;
rewrite /a(.*) /b$1;
rewrite /b(.*) /c$1 last;
rewrite /c(.*) /d$1 break;
location / {
if ($uri ~ /d/) {
rewrite /d/(.*) /api/$1 last;
}
return 200 '$uri';
}
location /api {
proxy_pass http://127.0.0.1:8000/test; #端口號後面有/,代理刪掉/api。
}
location ~ /t/(.*)/t {
proxy_pass http://127.0.0.1:8000/test1/$1;
#proxy_pass http://127.0.0.1:8000/test1; 寫法報錯,必須使用變量,使用第3條代理規則。
}
}
- 訪問/test 返回 /test
- 訪問/aaa 返回 /caa
- 訪問/api 返回 /cpi
- 訪問/d/dd 代理去
http://127.0.0.1:8000/test/dd
- 訪問/ee/t/test2/t/every 代理去
http://127.0.0.1:8000/test1/test2