nginx location rewrite經常使用詳解

location

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

匹配順序:

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

rewrite

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

執行順序
  1. 執行server塊的rewrite指令
  2. 執行location匹配
  3. 執行選定的location中的rewrite指令
語法

rewrite regex replacement [flag];app

flag

這兒分爲server級和location級,其中if可寫在server和location中,分別對應server級和location級。同級別中執行順序看書寫順序。
last : 再也不執行同級rewrite,寫在location中從新循環匹配location.
break : 再也不執行同級rewrite,隻日後繼續執行,不從新匹配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;code

一、 location 使用非正則匹配server

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最後是否有"/",是端口後面是否有"/"字符串

二、location 使用正則匹配域名

location ~ /api/ {
  proxy_pass http://127.0.0.1:8008;
}
  • 端口後面不加/,可行。
  • 端口後面加/,則必須使用變量(任何變量都行,讓其使用第3條規則)。由於代理地址會自動加上匹配剩餘的uri,代理去正則匹配剩餘的uri會使地址亂套。

三、若是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
相關文章
相關標籤/搜索