nginx location rewrite常用詳解

location

以 = 開頭,表示精確匹配;如只匹配根目錄結尾的請求,後面不能帶任何字符串。
以^~ 開頭,表示uri以某個常規字符串開頭,如果匹配到,則不繼續往下匹配。不是正則匹配
以~ 開頭,表示區分大小寫的正則匹配;
以~* 開頭,表示不區分大小寫的正則匹配
以/ 開頭,通用匹配, 如果沒有其它匹配,任何請求都會匹配到
*注意 location xxx {} 其中xxx與括號之間很多時候需要空格,最好都加上

匹配順序:

(location =) > (location 完整路徑) > (location ^~ 路徑) > (location ~,~* 正則順序) > (location 部分起始路徑) > (/)

rewrite

rewrite只能放在 server{}, location{}, if{}中,並且只能對域名後的文件路徑起作用。

執行順序
  1. 執行server塊的rewrite指令
  2. 執行location匹配
  3. 執行選定的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條代理規則。
  }
}
  1. 訪問/test 返回 /test
  2. 訪問/aaa 返回 /caa
  3. 訪問/api 返回 /cpi
  4. 訪問/d/dd 代理去 http://127.0.0.1:8000/test/dd
  5. 訪問/ee/t/test2/t/every 代理去 http://127.0.0.1:8000/test1/test2
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章