ngx_http_rewrite_module 模組
指令 break if return rewrite rewrite_log set uninitialized_variable_warn 內部實作 |
ngx_http_rewrite_module
模組用於使用 PCRE 正規表示式變更請求 URI、傳回重新導向,以及有條件地選取組態。
break、if、return、rewrite 和 set 指令會依下列順序處理:
- 在此模組中,於 server 層級指定的指令會依序執行;
- 重複地
指令
語法 |
break; |
---|---|
預設值 | — |
Context |
server 、location 、if |
停止處理目前設定的 ngx_http_rewrite_module
指令。
如果指令是在 location 內指定,則會在此 location 中繼續處理請求。
範例
if ($slow) { limit_rate 10k; break; }
語法 |
if ( |
---|---|
預設值 | — |
Context |
server 、location |
評估指定的 condition
。如果為 true,則會執行在此模組中,於大括號內指定的指令,且請求會被指派 if
指令內的組態。if
指令內的組態會繼承自先前的組態層級。
條件可以是下列任一項:
- 變數名稱;如果變數值為空字串或「
0
」,則為 false;在 1.0.1 版之前,任何以「
0
」開頭的字串都被視為 false 值。 - 使用「
=
」和「!=
」運算子比較變數與字串; - 使用「
~
」(用於區分大小寫比對) 和「~*
」(用於不區分大小寫比對) 運算子,比對變數與正規表示式。正規表示式可以包含捕捉,這些捕捉可在稍後重複使用於$1
..$9
變數中。負運算子「!~
」和「!~*
」也可用。如果正規表示式包含「}
」或「;
」字元,則整個表示式應該以單引號或雙引號括住。 - 使用「
-f
」和「!-f
」運算子檢查檔案是否存在; - 使用「
-d
」和「!-d
」運算子檢查目錄是否存在; - 使用「
-e
」和「!-e
」運算子檢查檔案、目錄或符號連結是否存在; - 使用「
-x
」和「!-x
」運算子檢查是否為可執行檔案。
範例
if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /msie/$1 break; } if ($http_cookie ~* "id=([^;]+)(?:;|$)") { set $id $1; } if ($request_method = POST) { return 405; } if ($slow) { limit_rate 10k; } if ($invalid_referer) { return 403; }
$invalid_referer
內嵌變數的值由 valid_referers 指令設定。
語法 |
return return return |
---|---|
預設值 | — |
Context |
server 、location 、if |
停止處理並將指定的 code
傳回給用戶端。非標準代碼 444 會關閉連線,而不傳送回應標頭。
從 0.8.42 版開始,可以指定重新導向 URL (適用於代碼 301、302、303、307 和 308) 或回應本文 text
(適用於其他代碼)。回應本文文字和重新導向 URL 可以包含變數。在特殊情況下,可以將重新導向 URL 指定為此伺服器的本機 URI,在這種情況下,完整重新導向 URL 會根據請求結構描述 ($scheme
) 和 server_name_in_redirect 與 port_in_redirect 指令形成。
此外,可以將代碼為 302 的臨時重新導向的 URL
指定為唯一的參數。此類參數應以「http://
」、「https://
」或「$scheme
」字串開頭。URL
可以包含變數。
在 0.7.51 版之前,只能傳回下列代碼:204、400、402 — 406、408、410、411、413、416 和 500 — 504。
在 1.1.16 和 1.0.13 版之前,代碼 307 未被視為重新導向。
在 1.13.0 版之前,代碼 308 未被視為重新導向。
另請參閱 error_page 指令。
語法 |
rewrite |
---|---|
預設值 | — |
Context |
server 、location 、if |
如果指定的正規表示式符合請求 URI,則會根據 replacement
字串中的指定變更 URI。rewrite
指令會依其在組態檔中出現的順序依序執行。可以使用旗標終止指令的進一步處理。如果取代字串以「http://
」、「https://
」或「$scheme
」開頭,則處理會停止,並將重新導向傳回給用戶端。
可選的 flag
參數可以是下列其中一項:
last
- 停止處理目前設定的
ngx_http_rewrite_module
指令,並開始搜尋符合變更後 URI 的新 location; break
- 停止處理目前設定的
ngx_http_rewrite_module
指令,如同 break 指令一樣; redirect
- 傳回代碼為 302 的臨時重新導向;如果取代字串不是以「
http://
」、「https://
」或「$scheme
」開頭,則會使用此旗標; permanent
- 傳回代碼為 301 的永久重新導向。
完整重新導向 URL 會根據請求結構描述 ($scheme
) 和 server_name_in_redirect 與 port_in_redirect 指令形成。
範例
server { ... rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last; rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last; return 403; ... }
但是,如果這些指令放在「/download/
」location 內,則 last
旗標應由 break
取代,否則 nginx 將會執行 10 個循環並傳回 500 錯誤
location /download/ { rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break; rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break; return 403; }
如果 replacement
字串包含新的請求引數,則會在其後附加先前的請求引數。如果不需要,則在取代字串的結尾加上問號,以避免附加這些引數,例如
rewrite ^/users/(.*)$ /show?user=$1? last;
如果正規表示式包含「}
」或「;
」字元,則整個表示式應該以單引號或雙引號括住。
語法 |
rewrite_log |
---|---|
預設值 |
rewrite_log off; |
Context |
http 、server 、location 、if |
啟用或停用將 ngx_http_rewrite_module
模組指令處理結果記錄到 notice
層級的 error_log 中。
語法 |
set |
---|---|
預設值 | — |
Context |
server 、location 、if |
為指定的 variable
設定 value
。value
可以包含文字、變數及其組合。
語法 |
uninitialized_variable_warn |
---|---|
預設值 |
uninitialized_variable_warn on; |
Context |
http 、server 、location 、if |
控制是否記錄關於未初始化變數的警告。
內部實作
ngx_http_rewrite_module
模組指令會在組態階段編譯成內部指令,這些指令會在請求處理期間解譯。解譯器是簡單的虛擬堆疊機器。
例如,以下指令:
location /download/ { if ($forbidden) { return 403; } if ($slow) { limit_rate 10k; } rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break; }
將轉換為下列指令:
variable $forbidden check against zero return 403 end of code variable $slow check against zero match of regular expression copy "/" copy $1 copy "/mp3/" copy $2 copy ".mp3" end of regular expression end of code
請注意,上面沒有 limit_rate 指令的指令,因為它與 ngx_http_rewrite_module
模組無關。會為 if 區塊建立個別的組態。如果條件成立,則會為請求指派此組態,其中 limit_rate
等於 10k。
以下指令:
rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;
如果將正規表示式中的第一個斜線放在括號內,則可以減少一個指令
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
對應的指令看起來會像這樣:
match of regular expression copy $1 copy "/mp3/" copy $2 copy ".mp3" end of regular expression end of code