Nginx 重寫URI

nginx_web發表於2012-06-30

重寫URI

 

    我們在使用Nginx的過程中經常碰到需要將客戶端訪問者的URI進行重寫,在“根據瀏覽器選擇主頁”部分多少有些認識這種做法,另外我們我們在“map模組的使用”部分也見到和改寫過,但是它們都沒有rewrite模組強大,因此,在這一部分我們看看rewrite的用法。

 

    使用rewrite模組離不開正規表示式,因此,要想使用rewrite指令,那麼就必須在安裝Nginx時指定pcre

 

使用該模組通過正規表示式(PCRE)就可以改變URI,並且可以重定向和根據變數來選擇配置。如果在server級別執行rewrite指令,那麼請求將在location確定之前執行。如果在被選擇的location中仍有rewrite指令,那麼它們同樣被執行,如果在這個location中又觸發訪問到rewrite指令,那麼就會再次改變URI。這種被重複週期為10才, 在10次之後仍然找不到具體的URI,那麼Nginx將會返回500錯誤。

 

配置示例

 

rewrite ^/(/d+)/(.+)/ /$2?id=$1 last;

 

rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;

 

if (-d $request_filename){

rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;

}

 

if ($http_host ~* "^(.*)/.st/.xx/.com$") {

rewrite ^(.*) http://st.yy.com$1;

break;

}

 

if ($host ~* (.*)\.xx\.com) {

           set $sub_name $1; 

           rewrite ^/sort\/(\d+)\/?$ /index.php?act=sort&cid=$sub_name&id=$1 last;

       }

 

if ($http_user_agent ~ MSIE) {

           rewrite ^(.*)$ /var/www/ie/$1 break;

}

   

 

安裝PCRE

 

    下載並安裝pcre

 

[root@s29 ~]# wget ftp://ftp.csx.cam.ac.uk/pub/software \

> /programming/pcre/pcre-8.13.tar.gz

[root@s29 ~]#tar -zxvf pcre-8.13.tar.gz

[root@s29 ~]#cd pcre-8.13

[root@s29 pcre-8.13]#./configure --prefix=/usr/local/pcre-8.13   \

> --enable-utf8 --enable-unicode-properties

[root@s29 pcre-8.13]#make

[root@s29 pcre-8.13]#make install

   

    需要注意的是,在安裝Nginx:

 

[root@mail nginx-1.0.2]# ./configure --prefix=/usr/local/nginx-1.0.2-pcre-8.13 \

> --with-pcre=/root/pcre-8.13

 

   ……

 

Configuration summary

  + using PCRE library: /root/pcre-8.13

  + OpenSSL library is not used

  + md5: using system crypto library

  + sha1 library is not used

  + using system zlib library

 

   ……

 

   

    這裡的--with-pcre指定的是pcre-8.13的原始碼,但是在Nginx的安裝過程中會查詢pcre安裝的具體情況:

 

.....//無法上傳省略

 

 

指令名稱:if

    : if (condition) { ... }

默 認 值: none

使用環境: server, location

    能:用於檢測條件是否成立,如果條件被評估為真,那麼在大括號“{}”中程式碼將會被執行,同配置中一致的請求將會被處理。if指令內部的配置會被從上一級繼承。需要注意的是,使用if指令要謹慎,儘量考慮是try_files指定。

 

條件condition部分可以指定下列值:

 

n  使用= !=操作符比較變數的表示式;

n  變數名稱,如果變數名稱為false,那麼值將會是一個空字串(""),或者是

任何以"0"開始的字串

n  使用正規表示式的模式匹配:

u             ~    執行區分大小寫匹配;

u             ~*   執行不區分大小寫匹配;

u             !~   執行區分大小寫不匹配

u             !~*  執行不區分大小寫不匹配

n  使用 -f 或者 !-f 操作符檢測檔案的存在性;

n  使用 -d 或者 !-d 操作符檢測目錄的存在性;

n  使用 -e 或者 !-e 操作符檢測檔案、目錄或者符號連線的存在性;

n  使用 -x 或者 !-x 檢測檔案是否可執行。

 

正規表示式部分可以放在括號內,以便在以後的使用中可以通過變數$1 $9來訪問。例如:

 

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;

}

 

if ($args ~ post=140){

  rewrite ^ http://example.com/ permanent;

}

 

 

        在條件判斷中可以使用的一些全域性變數:$args$content_length$content_type$document_root$document_uri$host$http_user_agent$http_cookie$limit_rate$request_body_file$request_method$remote_addr$remote_port$remote_user$request_filename$request_uri$query_string$scheme$server_protocol$server_addr$server_name$server_port$uri

 

指令名稱:return

    能: 該指令會結束執行規則,並且會為客戶端返回狀態碼。可使用的程式碼值:204, 400, 402-406, 408, 410, 411, 413, 416 500-504,此外,非標準的程式碼444將會關閉連線而不會傳送任何頭

    : return code

默 認 值: none

使用環境: server, location, if

 

指令名稱:rewrite

    : rewrite regex replacement flag

默 認 值: none

使用環境: server, location, if

    能:該指令會按照相關的regex正規表示式和replacement替換字串改變URIrewrite指令會按照自己在配置檔案中出現的順序執行,這一點要格外注意。

如果replacement替代字串由http://開始,那麼客戶端將會被重定向redirect,任何其它後面的rewrite指令都被終結。

 

標誌flag用於結束rewrite指令,它的可取值有:

 

l         last - 在搜尋到相應的URIlocation之後完成rewrite指令;

l         break - 完成 rewrite指令處理

l         redirect - 返回302臨時重定向,如果replacement替換部分是由http://開始,它將被應用。

l         permanent - 返回30程式碼永久重定向

 

注意,如果重定向是相當的,即沒有主機部分,那麼當使用重定向時,Nginx使用"Host"頭的順序為:如果有匹配server_name指令指定的主機名,那麼則使用它;如果沒有,那麼將會使用第一個server_name設定的值;如果仍然沒有,那麼本地主機名會被使用。如果想讓Nginx總是使用"Host"頭,那麼可以在server_name指令中使用"*"(但是這麼做會有限制)。例如:

 

rewrite ^(/download/.*)/media/(.*)\..*$  $1/mp3/$2.mp3  last;

rewrite ^(/download/.*)/audio/(.*)\..*$  $1/mp3/$2.ra   last;

return  403;

   

    如果我們將這些指令放置在/download/中,那麼有必要將標誌"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;

  

    注意使用大括號( { } ),由於它們可以同時使用在正規表示式和區段(就是httpserverlocationif)控制中,為了避免歧義、衝突,因此在正規表示式中使用大括號( { } )那麼將它們使用雙引號或者單引號來括起。例如:

 

    我們將/photos/123456  重定向該URL

 

/path/to/photos/12/1234/123456.png

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/27043155/viewspace-734211/,如需轉載,請註明出處,否則將追究法律責任。

相關文章