nginx proxy_pass和rewrite的區別
syntax: rewrite regex replacement [flag] Default: — Context: server, location, if
如果正則表達式(regex)匹配到了請求的URI(request URI),這個URI會被後面的replacement替換
rewrite的定向會根據他們在配置文件中出現的順序依次執行
通過使用flag可以終止定向後進一步的處理
如果replacement以“http://”, “https://”, or “$scheme”開頭,處理將會終止,請求結果會以重定向的形式返回給客戶端(client)
如果replacement字符串裏有新的request參數,那麽之前的參數會附加到其後面,如果要避免這種情況,那就在replacement
rewrite ^/users/(.*)$ /show?user=$1? last;=
如果正則表達式(regex)裏包含“}” or “;”字符,需要用單引號或者雙引號把正則表達式引起來
要把 http://www.test.com/a/b?id=123 的一條鏈接轉換成 http://www.test.com/p-123.html
在nginx中是有特殊邏輯,它用$query_string來表示問號以後的字符,即"id=123"
if ($request_uri ~* "^/a/b\?id=(\d+)$") {
set $myarg1 $1;
}註意,set $myarg1 $1; 這句話不能少,不能直接用$1,會出錯的。
可選的flag參數如下:
last
結束當前的請求處理,用替換後的URI重新匹配location;
可理解為重寫(rewrite)後,發起了一個新請求,進入server模塊,匹配location;
如果重新匹配循環的次數超過10次,nginx會返回500錯誤;
返回302 http狀態碼 ;
瀏覽器地址欄顯示重地向後的url
break
結束當前的請求處理,使用當前資源,不在執行location裏余下的語句;
返回302 http狀態碼 ;
瀏覽器地址欄顯示重地向後的url
redirect
臨時跳轉,返回302 http狀態碼;
瀏覽器地址欄顯示重地向後的url
permanent
永久跳轉,返回301 http狀態碼;
瀏覽器地址欄顯示重定向後的url
proxy_pass
Syntax: proxy_pass URL; Default: — Context: location, if in location, limit_except
不影響瀏覽器地址欄的url
設置被代理server的協議和地址,URI可選(可以有,也可以沒有)
協議可以為http或https
地址可以為域名或者IP,端口可選;eg:
proxy_pass http://localhost:8000/uri/;
如果一個域名可以解析到多個地址,那麽這些地址會被輪流使用,此外,還可以把一個地址指定為 server group(如:nginx的upstream), eg:
upstream backend { server backend1.example.com weight=5; server backend2.example.com:8080; server unix:/tmp/backend3; server backup1.example.com:8080 backup; server backup2.example.com:8080 backup; } server { location / { proxy_pass http://backend; } }
server name, port, URI支持變量的形式,eg:
proxy_pass http://$host$uri;
這種情況下,nginx會在server groups(upstream後端server)裏搜索server name,如果沒有找到,會用dns解析
請求的URI按照下面的規則傳給後端server
如果proxy_pass的URL定向裏包括URI,那麽請求中匹配到location中URI的部分會被proxy_pass後面URL中的URI替換,eg:
location /name/ { proxy_pass http://127.0.0.1/remote/;} 請求http://127.0.0.1/name/test.html 會被代理到http://example.com/remote/test.html
如果proxy_pass的URL定向裏不包括URI,那麽請求中的URI會保持原樣傳送給後端server,eg:
location /name/ { proxy_pass http://127.0.0.1;} 請求http://127.0.0.1/name/test.html 會被代理到http://127.0.0.1/name/test.html
一些情況下,不能確定替換的URI
location裏是正則表達式,這種情況下,proxy_pass裏最好不要有URI
在proxy_pass前面用了rewrite,如下,這種情況下,proxy_pass是無效的,eg:
location /name/ { rewrite /name/([^/]+) /users?name=$1 break; proxy_pass http://127.0.0.1;}
重寫規則語法: rewrite 正則 替換 標誌位
(1). 任何重寫規則第一部分肯定是 正則表達式
可以用()來捕獲正則表達式,然後在rewrite後面就用 $[d+] 來用這個正則表達式;比如:
^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$ ---->http://xxxx.com/images/aa/abc01/test.gif #其中 $1=([a-z]{2}) #$1=aa $2=([a-z0-9]{5}) #$2=abc01 $3=(.*) #$3=test $4=(png|jpg|gif) #$4=gif
上面的4個地段都是query 串中匹配的字符串
(2). 重寫規則的第二部分是URI(rewrite 重寫後url)
query 請求串被改寫,包括上面正則表達式獲取的參數字段和nginx 相關的配置,
/data?file=$3.$4 # rewrite之後的query http://data?file=test.gif
rewrite 之後會返回給客戶端301 或者302 [ 會不會返回200]
(3). 重寫規則的第三部分是:尾部的標記 flag last return break
laster 標記之後會從新loaction ,繼續rewrite 最多10次
rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4 last; #<pre name="code" class="html">http://xxxx.com/images/aa/abc01/test.gif -----rewrite---> http://data?file=test.gif
break標記是直接跳槽rewrite和localtion 進行query的處理if ($bwhog) {
if ($bwhog) { limit_rate 300k; break; }
return標記停止rewrite 處理指令,進而控制主HTTP 模塊處理請求,也就是HTTP請求也不處理了,直接給client 返回(結合error0page,)
location = /image404.html { return 404 "image not found\n"; }
(4). 整個過程的實例
http { server { root /home/www; location / { # 重寫規則信息 error_log logs/rewrite.log notice; # 註意這裏要用‘’單引號引起來,避免{} rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4; # 註意不能在上面這條規則後面加上“last”參數,否則下面的set指令不會執行 set $image_file $3; set $image_type $4; } location /data { rewrite /data?(.*) /error/img=$1 break; #break 就是最後的rewrite 結果,不會再次遍歷localtion啦 } location = /error/ { # 圖片不存在返回特定的信息 return 404 "image not found\n"; #如果是return HTTP 直接返回403 302 等狀態碼 } }
本文參考
https://blog.csdn.net/caoshuming_500/article/details/37700357
https://www.cnblogs.com/luxianghao/p/6807081.html
nginx proxy_pass和rewrite的區別