經過Rewrite規則能夠實現規範的URL、根據變量來作URL轉向及選擇配置,用好Rewrite有時起到事半功倍的效果。php
語法css
Nginx的Rewrite相比Apache的要好理解不少,主要使用指令有if、rewrite、set、return、break等,其中rewrite是最關鍵的指令。html
若是指定的正則表達式能匹配URI,此URI將被replacement參數定義的字符串改寫。rewrite指令按其在配置文件中出現的順序執行。flag能夠終止後續指令的執行。若是replacement的字符串以「http://」或「https://」開頭,nginx將結束執行過程,並返回給客戶端一個重定向。語法: rewrite regex replacement [flag];
默認值: —
上下文: server, location, if nginx
server { ... rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last; rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last; return 403; ... }
location /download/ { rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break; rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break; return 403; }
rewrite ^/users/(.*)$ /show?user=$1? last;
中止處理當前這一輪的ngx_http_rewrite_module指令集。如:語法: break;
默認值: —
上下文: server, location, if web
if ($slow) { limit_rate 10k; break; }
rewrite "/photos/([0-9]{2})([0-9]{2})([0-9]{2})" /path/to/photos/$1$2/$1$2$3.png>
用於檢查condition,若是爲真,執行定義在大括號中的rewrite模塊指令。if指令不支持嵌套,不支持多個條件&&和||處理。語法: if (condition) { ... }
默認值: —
上下文: server, location 正則表達式
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; }
爲指定變量variable設置變量值value。value能夠包含文本、變量或者它們的組合,舉例參考下文。語法: set variable value;
默認值: —
上下文: server, location, if 瀏覽器
開啓或者關閉將ngx_http_rewrite_module模塊指令的處理日誌以notice級別記錄到錯誤日誌中。語法: rewrite_log on | off;
默認值:
rewrite_log off;
上下文: http, server, location, if 緩存
控制是否記錄變量未初始化的警告到日誌。語法: uninitialized_variable_warn on | off;
默認值:
uninitialized_variable_warn on;
上下文: http, server, location, if 服務器
中止處理並返回指定code給客戶端。狀態碼可使用這些值:20四、400、402-40六、40八、4十、4十一、41三、416及500-504,此外,非標準狀態碼444將以不發送任何Header頭的方式結束連接。語法: return code [text];
return code URL;
return URL;
默認值: —
上下文: server, location, if cookie
nginx用到的全局變量
$arg_PARAMETER #這個變量包含GET請求中,若是有變量PARAMETER時的值。 $args #這個變量等於請求行中(GET請求)的參數,例如foo=123&bar=blahblah; $binary_remote_addr #二進制的客戶地址。 $body_bytes_sent #響應時送出的body字節數數量。即便鏈接中斷,這個數據也是精確的。 $content_length #請求頭中的Content-length字段。 $content_type #請求頭中的Content-Type字段。 $cookie_COOKIE #cookie COOKIE變量的值 $document_root #當前請求在root指令中指定的值。 $document_uri #與$uri相同。 $host #請求主機頭字段,不然爲服務器名稱。 $hostname #Set to the machine’s hostname as returned by gethostname $http_HEADER $is_args #若是有$args參數,這個變量等於」?」,不然等於」",空值。 $http_user_agent #客戶端agent信息 $http_cookie #客戶端cookie信息 $limit_rate #這個變量能夠限制鏈接速率。 $query_string #與$args相同。 $request_body_file #客戶端請求主體信息的臨時文件名。 $request_method #客戶端請求的動做,一般爲GET或POST。 $remote_addr #客戶端的IP地址。 $remote_port #客戶端的端口。 $remote_user #已經通過Auth Basic Module驗證的用戶名。 $request_completion #若是請求結束,設置爲OK. 當請求未結束或若是該請求不是請求鏈串的最後一個時,爲空(Empty)。 $request_method #GET或POST $request_filename #當前請求的文件路徑,由root或alias指令與URI請求生成。 $request_uri #包含請求參數的原始URI,不包含主機名,如:」/foo/bar.php?arg=baz」。不能修改。 $scheme #HTTP方法(如http,https)。 $server_protocol #請求使用的協議,一般是HTTP/1.0或HTTP/1.1。 $server_addr #服務器地址,在完成一次系統調用後能夠肯定這個值。 $server_name #服務器名稱。 $server_port #請求到達服務器的端口號。 $uri #不帶請求參數的當前URI,$uri不包含主機名,如」/foo/bar.html」。該值有可能和$request_uri 不一致。$request_uri是瀏覽器發過來的值。該值是rewrite後的值。例如作了internal redirects後。
Rewrite規則實例
if( !-e $request_filename ) { rewrite ^/(.*)$ index.php last; }
rewrite ^/(\d+)/(.+)/ /$2?id=$1 last;
if( $http_user_agent ~ MSIE) { rewrite ^(.*)$ /ie/$1 break; }
location ~ ^/(cron|templates)/ { deny all; break; }
location ~ ^/data { deny all; }
location ~ .*\.(sh|flv|mp3)$ { return 403; }
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } location ~ .*\.(js|css)$ { expires 1h; }
Nginx和Apache的Rewrite規則實例對比
#Apache RewriteRule ^/abc/$ /web/abc.php [L] #Nginx rewrite ^/abc/$ /web/abc.php last ;
rewrite "^/([0-9]{5}).html$" /x.php?id=$1 last;
#Apache RewriteRule ^/html/([a-zA-Z]+)/.*$ /$1/ [R=301,L] #Nginx rewrite ^/html/([a-zA-Z]+)/.*$ http://$host/$1/ premanent;
RewriteCond %{HTTP_HOST} !^(.*?)\.aaa\.com$ [NC] RewriteCond %{HTTP_HOST} !^localhost$ RewriteCond %{HTTP_HOST} !^192\.168\.0\.(.*?)$ RewriteRule ^/(.*)$ http://www.xiaozhe.com [R,L]
if( $host ~* ^(.*)\.aaa\.com$ ) { set $allowHost ‘1’; } if( $host ~* ^localhost ) { set $allowHost ‘1’; } if( $host ~* ^192\.168\.1\.(.*?)$ ) { set $allowHost ‘1’; } if( $allowHost !~ ‘1’ ) { rewrite ^/(.*)$ http://www.xiaozhe.com redirect ; }