這是 Nginx 學習總結的第四篇,上一篇介紹到了 Nginx 學習總結(3) —— Location 模塊,這一篇會對Rewrite模塊
作一些總結。根據官方文檔說明,Rewrite
模塊是用於使用 PCRE 正則表達式
更改請求 URI,有條件地選擇配置,並返回重定向。php
表面看,rewrite
和location
的功能有點像,都能實現跳轉,然而它們的區別在於:rewrite
是在同一域名內更改獲取資源的路徑,而location
是對一類路徑作控制訪問或反向代理,而且能夠proxy_pass
到其餘機器。
不少狀況下 rewrite
也會寫在 location
裏,它們的執行順序是:html
server
塊的 rewrite
指令;location
匹配;location
中的 rewrite
指令。
若是其中某步 URI 被重寫,則從新循環執行1-3,直到找到真實存在的文件;循環超過10次,則返回
500 Internal Server Error
錯誤。
中止執行 ngx_http_rewrite_module
模塊的指令集,可是其餘模塊指令不受影響。nginx
Context: server, location, if
server { listen 80; # 此處 break 會中止執行 server 塊的 return 指令(return 指令屬於rewrite模塊) # 若是把它註釋掉 則全部請求進來都返回 ok 字符串 break; return 200 "ok"; location = / { root /usr/share/nginx/html; index index.php index.html index.htm; } }
依據指定的條件決定是否執行 if 塊語句中的內容。正則表達式
Context: server, location
if
中的幾種判斷條件:segmentfault
$variable
的值爲空字符串或者字符串 "0"
,則爲 false
;=
不相等爲 !=
;~
區分大小寫的正則匹配; ~*
不區分大小寫的正則匹配, !~
、!~*
前面二者的非;-f
(存在) 和 !-f
(不存在);-d
(存在) 和 !-d
(不存在) 後面判斷能夠是字符串也但是變量;-e
(存在) 和 !-e
(不存在) ,後面判斷能夠是字符串也但是變量;-x
(可執行) 和 !-x
(不可執行),後面判斷能夠是字符串也但是變量。能夠用做 if
判斷的全局變量:瀏覽器
$args
這個變量等於請求行中的參數,同 $query_string
$content_length
請求頭中的 Content-length
字段$content_type
請求頭中的 Content-Type
字段$document_root
當前請求在 root
指令中指定的值$host
請求主機頭字段,不然爲服務器名稱$http_user_agent
客戶端 agent
信息$http_cooki
客戶端 cookie
信息$limit_rate
這個變量能夠限制鏈接速率$request_method
客戶端請求的動做,一般爲 GET
或 POST
$remote_addr
客戶端的 IP 地址$remote_port
客戶端的端口$remote_user
已經通過 Auth Basic Module
驗證的用戶名$request_filename
當前請求的文件路徑,由 root
或 alias
指令與 URI 請求生成$scheme
請求協議,如 http,https$server_protocol
請求客戶端協議,一般是 HTTP/1.0
或 HTTP/1.1
$server_addr
服務器地址,在完成一次系統調用後能夠肯定這個值$server_name
服務器名稱$server_port
請求到達服務器的端口號$request_uri
包含請求參數的原始 URI,不包含主機名,如 /foo/bar.php?arg=baz
$uri
不帶請求參數的當前 URI,$uri 不包含主機名,如 /foo/bar.html
$document_uri
與 $uri 相同set $variable "0"; if ($variable) { # 不會執行,由於 "0" 爲 false break; } # 變量與一個字符串的比較 if ($request_method = POST) { return 405; } # 變量與正則表達式的匹配 if ($http_cookie ~* "id=([^;]+)(?:;|$)") { set $id $1; } if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /msie/$1 break; } # 檢查文件是否存在,字符串與變量都可 if ( !-f "/data.log" ) { break; } if ( !-f $filename ) { break; }
if
關鍵字後必須加一個空格符
中止處理並將指定的 code
碼返回給客戶端。 從 0.8.42 版本開始, return
語句能夠指定重定向 URL (狀態碼能夠爲以下幾種 301,302,303,307),也能夠爲其餘狀態碼指定響應的文本內容,而且重定向的 URL 和響應的文本能夠包含變量。服務器
Context: server, location, if
# return code [text]; location = /ok { return 200 "ok"; # 返回 ok 給客戶端 } # return code URL; location = /redirect { return 302 http://www.baidu.com; # 臨時重定向 } # return URL; location = /redirect { return http://www.baidu.com; # 臨時重定向 }
使用指定的正則表達式匹配請求 URL,若是匹配成功,則根據規則更改 URL。rewrite
指令按照它們在配置文件中出現的前後順序執行。可使用 flag
標誌來終止指令的進一步處理。若是替換字符串以 http://
、https://
或 $scheme
開頭,則中止處理後續內容,並直接重定向返回給客戶端。語法:rewrite regex replacement [flag];
cookie
Context: server, location, if
# 第一種狀況,帶 http:// location / { rewrite /test1/(.*) http://www.$1.com; return 200 "ok"; } # 在瀏覽器中訪問,被臨時重定向到 www.baidu.com # 後面的 return 指令將沒有機會執行了 # 第二種狀況,不帶 http:// location / { rewrite /test1/(.*) www.$1.com; return 200 "ok"; } # 在瀏覽器中訪問,返回了 ok
rewrite
的四個 flag
:curl
last
中止處理當前的 ngx_http_rewrite_module
的指令集,並開始搜索與更改後的 URL 相匹配的 location;break
中止處理當前的 ngx_http_rewrite_module
指令集;redirect
返回 302 臨時重定向;permanent
返回 301 永久重定向。location / { # 順序執行以下兩條 rewrite 指令 # rewrite 後面沒有任何 flag 時就順序執行 # 當 location 中沒有 rewrite 模塊指令可被執行時,就重寫發起新一輪 location 匹配 rewrite ^/test1 /test2; rewrite ^/test2 /test3; # 此處發起新一輪location匹配,重寫後的 url 爲 /test3 } location = /test2 { return 200 "/test2"; } location = /test3 { return 200 "/test3"; } # 發送以下請求 # curl 127.0.0.1:8080/test1 # /test3
location / { rewrite ^/test1 /test2; rewrite ^/test2 /test3 last; # 此處發起新一輪 location 匹配,重寫後的 url 爲 /test3 rewrite ^/test3 /test4; } location = /test2 { return 200 "/test2"; } location = /test3 { return 200 "/test3"; } location = /test4 { return 200 "/test4"; } # 發送以下請求 # curl 127.0.0.1:8080/test1 # /test3
location / { rewrite ^/test1 /test2; rewrite ^/test2 /more/index.html break; # 終止執行後續 rewrite 模塊指令,重寫後的 url 爲 /more/index.html rewrite /more/index.html /test4; proxy_pass https://www.baidu.com; # 由於 proxy_pass 不是 rewrite 模塊的指令,因此它不會被 break 終止 } # 發送以下請求 # curl 127.0.0.1:8080/test1 # 代理到 百度產品大全頁面: https://www.baidu.com/more/index.html;
開啓或者關閉 rewrite
模塊指令的執行日誌,若是開啓,則記錄下 notice
級別的日誌到 error_log
中,默認爲關閉 off
。學習
Context: http, server, location, if
設置指定變量的值。變量的值能夠包含文本,變量或者是它們的組合形式。
Context: server, location, if
location / { set $var1 "host is "; set $var2 $host; set $var3 " uri is $request_uri"; return 200 "response ok $var1$var2$var3"; } # 發送以下請求 # curl 127.0.0.1:8080/test # response ok host is 127.0.0.1 uri is /test
參考文章: