nginx通過ngx_http_rewrite_module模塊支持url重寫、支持if條件判斷,但不支持else。該模塊需要PCRE支持。
nginx rewrite指令執(zhí)行順序:
1.執(zhí)行sever塊的rewrite指令(這里的塊指的是sever關鍵字后{}包圍的區(qū)域,其它xx塊類似)
2.執(zhí)行l(wèi)ocation匹配
3.執(zhí)行選定的location中的rewrite指令
如果其中某步URI被重寫,則重新循環(huán)執(zhí)行1-3,直到找到真實存在的文件;如果循環(huán)超過10次,則返回500 Internal Server Error錯誤
break 指令
語法:break;
默認值:無
作用域:server,location,if
功能:停止執(zhí)行當前虛擬主機的后續(xù)rewrite指令集
例:
if ($slow) {
limit_rate 10k;
break;
}
if 指令
語法:if(condition){...}
默認值:無
作用域:server,location
功能:對給定的條件condition進行判斷。如果為真,大括號內的rewrite指令將被執(zhí)行。
if條件(conditon)可以是如下任何內容:
一個變量名;false如果這個變量是空字符串或者以0開始的字符串;
使用= ,!= 比較的一個變量和字符串
是用~, ~*與正則表達式匹配的變量,如果這個正則表達式中包含},;則整個表達式需要用" 或'
包圍
使用-f ,!-f 檢查一個文件是否存在
使用-d, !-d 檢查一個目錄是否存在
使用-e ,!-e 檢查一個文件、目錄、符號鏈接是否存在
使用-x , !-x 檢查一個文件是否可執(zhí)行
例:
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;
}
return 指令
語法1:return code;
語法2:return code URL;
語法3:return URL;
默認值:無
作用域:server,location,if
功能:停止處理規(guī)則并返回指定狀態(tài)碼(code)給客戶端;非標準狀態(tài)碼444表示關閉連接且不給客戶端發(fā)響應頭;從0.8.42版本起,return支持響應URL重定向(對于301,302,303,307),或者文本響應(對于其他狀態(tài)碼);對于文本或者URL重定向可以包含變量。
例:
server {
listen 80;
server_name 192.168.21.69;
return 301 https://$server_name$request_uri;
}
if (!-e $request_filename) {
return 404;
}
rewrite指令
語法:rewrite regex replacement [flag];
默認值:無
作用域:server,location,if
功能:如果一個URI匹配指定的正則表達式regex,URI就按照replacement重寫。
說明:rewrite按配置文件中出現的順序執(zhí)行。flags標志可以停止繼續(xù)處理。
如果replacement以"http://"或"https://"開始,將不再繼續(xù)處理,這個重定向將返回給客戶端。
flag可以是如下參數:
last
停止處理后續(xù)rewrite指令集,然后對當前重寫的新URI在rewrite指令集上重新查找。
break
停止處理后續(xù)rewrite指令集,并不在重新查找,但是當前l(fā)ocation內剩余非rewrite語句和location外的的非rewrite語句可以執(zhí)行。
redirect
如果replacement不是以http://
或https://開始,返回302臨時重定向
permant
返回301永久重定向
最終完整的重定向URL包括請求scheme(http://,https://等),請求的server_name_in_redirect和 port_in_redirec三部分,說白了也就是http協議、域名、端口三部分組成。
例:
server {
...
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
return 403;
...
}
如果這些rewrite放到 “/download/” location如下所示, 那么應使用break而不是last , 使用last將循環(huán)10次匹配,然后返回 500錯誤:
location /download/ {
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
return 403;
}
對于重寫后的URL(replacement)包含原請求的請求參數,原URL的?后的內容。如果不想帶原請求的參數 ,可以在replacement后加一個問號。如下,我們加了一個自定義的參數user=$1,然后在結尾處放了一個問號?,把原請的參數去掉。
rewrite ^/users/(.*)$ /show?user=$1? last;
如果正則表達regex式中包含 “}” 或 “;”, 那么整個表達式需要用雙引號或單引號包圍。
rewrite_log 指令
語法:rewrite_log on|off;
默認值:rewrite_log off;
作用域:http,server,location,if
功能:開啟或關閉以notice級別打印rewrite處理日志到error log文件。
nginx打開rewrite log例子
rewrite_log on;
error_log logs/xxx.error.log notice;
1.打開rewrite on
2.把error log的級別調整到 notice
set指令
語法:set variable value;
默認值:none
作用域:server,location,if
功能:定義一個變量并賦值,值可以是文本,變量或者文本變量混合體。
uninitialized_variable_warn 指令
語法:uninitialized_variable_warn on | off;
默認值:uninitialized_variable_warn on
作用域:http,server,location,if
功能:控制是否輸出為初始化的變量到日志
一些可用的全局變量有,可以用做條件判斷(不完整收集):
變量 | 說明 |
$args | 此變量與請求行中的參數相等,與$query_string等價。如:foo=123&bar=blahblah; |
$content_length | 等于請求行的“Content_Length”的值 |
$content_type | 等同與請求頭部的”Content_Type”的值 |
$document_root | 等同于當前請求的root指令指定的值 |
$document_uri | 等同于當前request中的URI,可不同于初始值,與$uri同。例如內部重定向時或使用index |
$host | 與請求頭部中“Host”行指定的值或是request到達的server的名字(沒有Host行)一樣 |
$http_user_agent | 客戶端代理信息 |
$http_cookie | cookie 信息 |
$limit_rate | 對連接速率的限制; |
$request_body_file | 發(fā)往后端的本地文件名稱 |
$request_method | 請求的方法,比如"GET"、"POST"等; |
$remote_addr | 客戶端地址; |
$remote_port | 客戶端端口號; |
$remote_user | 客戶端用戶名,認證用; |
$request_filename | 當前請求的文件路徑名 |
$request_uri | 請求的URI,帶參數; |
$query_string | 此變量與請求行中的參數相等,,與$args等價。 |
$scheme | 所用的協議,比如http或者是https,比如rewrite^(.+)$$scheme://example.com$1redirect; |
$server_protocol | 請求的協議版本,"HTTP/1.0"或"HTTP/1.1"; |
$server_addr | 服務器地址,如果沒有用listen指明服務器地址,使用這個變量將發(fā)起一次系統調用以取得地址(造成資源浪費); |
$server_name | 請求到達的服務器名; |
$server_port | 請求到達的服務器端口號; |
$uri | 請求的URI,可能和最初的值有不同,比如經過重定向之類的。 |
官方文檔:http://nginx.org/en/docs/http/ngx_http_rewrite_module.html