歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> 關於Linux >> Nginx之URL重寫

Nginx之URL重寫

日期:2017/3/1 11:44:52   编辑:關於Linux

1.URL重寫模塊(Rewrite)

摘要

這個模塊允許使用正則表達式重寫URI(需PCRE庫),並且可以根據相關變量重定向和選擇不同的配置。如果這個指令在server字段中指定,那麼將在被請求的location確定之前執行,如果在指令執行後所選擇的location中有其他的重寫規則,那麼它們也被執行。如果在location中執行這個指令產生了新的URI,那麼location又一次確定了新的URI。這樣的循環可以最多執行10次,超過以後nginx將返回500錯誤。

指令

break

語法:break

默認值:none

使用字段:server, location, if

完成當前設置的規則,停止執行其他的重寫指令。

示例:

1.URL重寫模塊(Rewrite)

摘要

這個模塊允許使用正則表達式重寫URI(需PCRE庫),並且可以根據相關變量重定向和選擇不同的配置。如果這個指令在server字段中指定,那麼將在被請求的location確定之前執行,如果在指令執行後所選擇的location中有其他的重寫規則,那麼它們也被執行。如果在location中執行這個指令產生了新的URI,那麼location又一次確定了新的URI。這樣的循環可以最多執行10次,超過以後nginx將返回500錯誤。

指令

break

語法:break

默認值:none

使用字段:server, location, if

完成當前設置的規則,停止執行其他的重寫指令。

示例:

1.URL重寫模塊(Rewrite)

摘要

這個模塊允許使用正則表達式重寫URI(需PCRE庫),並且可以根據相關變量重定向和選擇不同的配置。如果這個指令在server字段中指定,那麼將在被請求的location確定之前執行,如果在指令執行後所選擇的location中有其他的重寫規則,那麼它們也被執行。如果在location中執行這個指令產生了新的URI,那麼location又一次確定了新的URI。這樣的循環可以最多執行10次,超過以後nginx將返回500錯誤。

指令

break

語法:break

默認值:none

使用字段:server, location, if

完成當前設置的規則,停止執行其他的重寫指令。

示例:

if ($slow) {
  limit_rate  10k;
  break;
}

if

語法:if (condition) { … }

默認值:none

使用字段:server, location

注意:在使用if指令之前請查看if is evil page並且盡量考慮用try_files代替。

判斷一個條件,如果條件成立,則後面的大括號內的語句將執行,相關配置從上級繼承。

可以在判斷語句中指定下列值:

一個變量的名稱;不成立的值為:空字符傳”“或者一些用“0”開始的字符串。

一個使用=或者!=運算符的比較語句。

使用符號~*和~模式匹配的正則表達式:

~為區分大小寫的匹配。

~*不區分大小寫的匹配(firefox匹配FireFox)。

!~和!~*意為“不匹配的”。

使用-f和!-f檢查一個文件是否存在。

使用-d和!-d檢查一個目錄是否存在。

使用-e和!-e檢查一個文件,目錄或者軟鏈接是否存在。

使用-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 (!-f $request_filename) {

break;

proxy_pass http://127.0.0.1;

}

if ($slow) {

limit_rate 10k;

}

if ($invalid_referer) {

return 403;

}

if ($args ~ post=140){

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

}

內置變量$invalid_referer用指令valid_referers指定。

return

語法:return code

默認值:none

使用字段:server, location, if

這個指令結束執行配置語句並為客戶端返回狀態代碼,可以使用下列的值:204,400,402-406,408,410, 411, 413, 416與500-504。此外,非標准代碼444將關閉連接並且不發送任何的頭部。

rewrite

語法:rewrite regex replacement flag

默認值:none

使用字段:server, location, if

按照相關的正則表達式與字符串修改URI,指令按照在配置文件中出現的順序執行。

可以在重寫指令後面添加標記。

如果替換的字符串以http://開頭,請求將被重定向,並且不再執行多余的rewrite指令。

尾部的標記(flag)可以是以下的值:

last - 完成重寫指令,之後搜索相應的URI或location。

break - 完成重寫指令。

redirect - 返回302臨時重定向,如果替換字段用http://開頭則被使用。

permanent - 返回301永久重定向。

注意如果一個重定向是相對的(沒有主機名部分),nginx將在重定向的過程中使用匹配server_name指令的“Host”頭或者server_name指令指定的第一個名稱,如果頭不匹配或不存在,如果沒有設置server_name,將使用本地主機名,如果你總是想讓nginx使用“Host”頭,可以在server_name使用“*”通配符(查看http核心模塊中的server_name)。例如:

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;
}

如果替換字段中包含參數,那麼其余的請求參數將附加到後面,為了防止附加,可以在最後一個字符後面跟一個問號:

rewrite ^/users/(.*)$ /show?user=$1? last;

注意:大括號({和}),可以同時用在正則表達式和配置塊中,為了防止沖突,正則表達式使用大括號需要用雙引號(或者單引號)。例如要重寫以下的URL:

/photos/123456

為:

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

則使用以下正則表達式(注意引號):

rewrite "/photos/([0-9] {2})([0-9] {2})([0-9] {2})" /path/to/photos/$1/$1$2/$1$2$3.png;

如果指定一個“?”在重寫的結尾,Nginx將丟棄請求中的參數,即變量$args,當使用$request_uri或$uri&$args時可以在rewrite結尾使用“?”以避免nginx處理兩次參數串。

在rewrite中使用$request_uri將www.example.com重寫到example.com:

server {
   server_name www.example.com;
   rewrite ^ http://example.com$request_uri? permanent;
}

同樣,重寫只對路徑進行操作,而不是參數,如果要重寫一個帶參數的URL,可以使用以下代替:

if ($args ^~ post=100){
  rewrite ^ http://example.com/new-address.html? permanent;
}

注意$args變量不會被編譯,與location過程中的URI不同(參考http核心模塊中的location)。

rewrite_log

語法:rewrite_log on | off

默認值:rewrite_log off

使用字段:server, location, if

變量:無

啟用時將在error log中記錄notice 標記的重寫日志。

set

語法:set variable value

默認值:none

使用字段:server, location, if

指令設置一個變量並為其賦值,其值可以是文本,變量和它們的組合。

你可以使用set定義一個新的變量,但是不能使用set設置$http_xxx頭部變量的值。

uninitialized_variable_warn

語法:uninitialized_variable_warn on|off

默認值:uninitialized_variable_warn on

使用字段:http, server, location, if

開啟或關閉在未初始化變量中記錄警告日志。

事實上,rewrite指令在配置文件加載時已經編譯到內部代碼中,在解釋器產生請求時使用。

這個解釋器是一個簡單的堆棧虛擬機,如下列指令:

location /download/ {
  if ($forbidden) {
    return   403;
  }
  if ($slow) {
    limit_rate  10k;
  }
  rewrite  ^/(download/.*)/media/(.*)\..*$  /$1/mp3/$2.mp3  break;

將被編譯成以下順序:

variable $forbidden
  checking to zero
  recovery 403
  completion of entire code
  variable $slow
  checking to zero
  checkings of regular excodession
  copying "/"
  copying $1
  copying "/mp3/"
  copying $2
  copying ".mp3"
  completion of regular excodession
  completion of entire sequence

注意並沒有關於limit_rate的代碼,因為它沒有提及ngx_http_rewrite_module模塊,“if”塊可以類似”location”指令在配置文件的相同部分同時存在。

如果$slow為真,對應的if塊將生效,在這個配置中limit_rate的值為10k。

指令:

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

如果我們將第一個斜槓括入圓括號,則可以減少執行順序:

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

之後的順序類似如下:

 checking regular excodession
  copying $1
  copying "/mp3/"
  copying $2
  copying ".mp3"
  completion of regular excodession
  completion of entire code

2.簡單案例

注,由於配置文件內容較多,為了讓大家看著方便,我們備份一下配置文件,打開一個新的配置文件。

[root@nginx ~]# cd /etc/nginx/ [root@nginx nginx]# mv nginx.conf nginx.conf.proxy [root@nginx nginx]# cp nginx.conf.bak nginx.conf [root@nginx nginx]# vim /etc/nginx/nginx.conf server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; rewrite ^/bbs/(.*)$ http://192.168.18.201/forum/$1; } }

准備forum目錄與測試文件

1 2 3 4 5 6 7[root@web1 ~]# cd /var/www/html/ [root@web1 html]# ls index.html [root@web1 html]# mkdir forum [root@web1 html]# cd forum/ [root@web1 forum]# vim index.html

forum page!

測試一下

\

好了,下面我們來測試一下rewrite重寫。

3.重新加載一下配置文件

1 2 3 4[root@nginx 63]# service nginx reload nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful 重新載入 nginx: [確定]

4.測試一下

\

注,大家可以從圖中看出,status code 302指的是臨時重定向,那就說明我們rewrite重寫配置成功。大家知道302是臨時重定向而301是永久重定向,那麼怎麼實現永久重定向呢。一般服務器與服務器之間是臨時重定向,服務器內部是永久重定向。下面我們來演示一下永久重定向。

5.配置永久重定向

1 2 3 4 5 6 7 8 9 10 11 12[root@nginx nginx]# vim /etc/nginx/nginx.conf server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; rewrite ^/bbs/(.*)$ /forum/$1; } }

准備forum目錄與測試文件

1 2 3 4 5 6 7[root@nginx ~]# cd /usr/html/ [root@nginx html]# ls 50x.html index.html [root@nginx html]# mkdir forum [root@nginx html]# cd forum/ [root@nginx forum]# vim index.html

192.168.18.208 forum page

6.重新加載一下配置文件

1 2 3 4[root@nginx ~]# service nginx reload nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful 重新載入 nginx: [確定]

7.測試一下

\

注,大家從圖中可以看到,我們訪問bbs/是直接幫我們跳轉到forum/下,這種本機的跳轉就是永久重定向也叫隱式重定向。好了,rewrite重定向我們就說到這裡了,想要查詢更多關於重定向的指令請參考官方文檔。最後,我們來說一下讀寫分離。

if

語法:if (condition) { … }

默認值:none

使用字段:server, location

注意:在使用if指令之前請查看if is evil page並且盡量考慮用try_files代替。

判斷一個條件,如果條件成立,則後面的大括號內的語句將執行,相關配置從上級繼承。

可以在判斷語句中指定下列值:

一個變量的名稱;不成立的值為:空字符傳”“或者一些用“0”開始的字符串。

一個使用=或者!=運算符的比較語句。

使用符號~*和~模式匹配的正則表達式:

~為區分大小寫的匹配。

~*不區分大小寫的匹配(firefox匹配FireFox)。

!~和!~*意為“不匹配的”。

使用-f和!-f檢查一個文件是否存在。

使用-d和!-d檢查一個目錄是否存在。

使用-e和!-e檢查一個文件,目錄或者軟鏈接是否存在。

使用-x和!-x檢查一個文件是否為可執行文件。

正則表達式的一部分可以用圓括號,方便之後按照順序用$1-$9來引用。

示例配置:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /msie/$1 break; } if ($http_cookie ~* "id=([^;] +)(?:;|$)" ) { set $id $1; } if ($request_method = POST ) { return 405; } if (!-f $request_filename) { break; proxy_pass http://127.0.0.1; } if ($slow) { limit_rate 10k; } if ($invalid_referer) { return 403; } if ($args ~ post=140){ rewrite ^ http://example.com/ permanent; }

內置變量$invalid_referer用指令valid_referers指定。

return

語法:return code

默認值:none

使用字段:server, location, if

這個指令結束執行配置語句並為客戶端返回狀態代碼,可以使用下列的值:204,400,402-406,408,410, 411, 413, 416與500-504。此外,非標准代碼444將關閉連接並且不發送任何的頭部。

rewrite

語法:rewrite regex replacement flag

默認值:none

使用字段:server, location, if

按照相關的正則表達式與字符串修改URI,指令按照在配置文件中出現的順序執行。

可以在重寫指令後面添加標記。

如果替換的字符串以http://開頭,請求將被重定向,並且不再執行多余的rewrite指令。

尾部的標記(flag)可以是以下的值:

last - 完成重寫指令,之後搜索相應的URI或location。

break - 完成重寫指令。

redirect - 返回302臨時重定向,如果替換字段用http://開頭則被使用。

permanent - 返回301永久重定向。

注意如果一個重定向是相對的(沒有主機名部分),nginx將在重定向的過程中使用匹配server_name指令的“Host”頭或者server_name指令指定的第一個名稱,如果頭不匹配或不存在,如果沒有設置server_name,將使用本地主機名,如果你總是想讓nginx使用“Host”頭,可以在server_name使用“*”通配符(查看http核心模塊中的server_name)。例如:

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

但是如果我們將其放入一個名為/download/的location中,則需要將last標記改為break,否則nginx將執行10次循環並返回500錯誤。

1 2 3 4 5location /download/ { rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break; rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break; return 403; }

如果替換字段中包含參數,那麼其余的請求參數將附加到後面,為了防止附加,可以在最後一個字符後面跟一個問號:

1rewrite ^/users/(.*)$ /show?user=$1? last;

注意:大括號({和}),可以同時用在正則表達式和配置塊中,為了防止沖突,正則表達式使用大括號需要用雙引號(或者單引號)。例如要重寫以下的URL:

1/photos/123456

為:

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

則使用以下正則表達式(注意引號):

1rewrite "/photos/([0-9] {2})([0-9] {2})([0-9] {2})" /path/to/photos/$1/$1$2/$1$2$3.png;

如果指定一個“?”在重寫的結尾,Nginx將丟棄請求中的參數,即變量$args,當使用$request_uri或$uri&$args時可以在rewrite結尾使用“?”以避免nginx處理兩次參數串。

在rewrite中使用$request_uri將www.example.com重寫到example.com:

1 2 3 4server { server_name www.example.com; rewrite ^ http://example.com$request_uri? permanent; }

同樣,重寫只對路徑進行操作,而不是參數,如果要重寫一個帶參數的URL,可以使用以下代替:

1 2 3if ($args ^~ post=100){ rewrite ^ http://example.com/new-address.html? permanent; }

注意$args變量不會被編譯,與location過程中的URI不同(參考http核心模塊中的location)。

rewrite_log

語法:rewrite_log on | off

默認值:rewrite_log off

使用字段:server, location, if

變量:無

啟用時將在error log中記錄notice 標記的重寫日志。

set

語法:set variable value

默認值:none

使用字段:server, location, if

指令設置一個變量並為其賦值,其值可以是文本,變量和它們的組合。

你可以使用set定義一個新的變量,但是不能使用set設置$http_xxx頭部變量的值。

uninitialized_variable_warn

語法:uninitialized_variable_warn on|off

默認值:uninitialized_variable_warn on

使用字段:http, server, location, if

開啟或關閉在未初始化變量中記錄警告日志。

事實上,rewrite指令在配置文件加載時已經編譯到內部代碼中,在解釋器產生請求時使用。

這個解釋器是一個簡單的堆棧虛擬機,如下列指令:

1 2 3 4 5 6 7 8location /download/ { if ($forbidden) { return 403; } if ($slow) { limit_rate 10k; } rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;

將被編譯成以下順序:

1 2 3 4 5 6 7 8 9 10 11 12 13 14variable $forbidden checking to zero recovery 403 completion of entire code variable $slow checking to zero checkings of regular excodession copying "/" copying $1 copying "/mp3/" copying $2 copying ".mp3" completion of regular excodession completion of entire sequence

注意並沒有關於limit_rate的代碼,因為它沒有提及ngx_http_rewrite_module模塊,“if”塊可以類似”location”指令在配置文件的相同部分同時存在。

如果$slow為真,對應的if塊將生效,在這個配置中limit_rate的值為10k。

指令:

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

如果我們將第一個斜槓括入圓括號,則可以減少執行順序:

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

之後的順序類似如下:

1 2 3 4 5 6 7checking regular excodession copying $1 copying "/mp3/" copying $2 copying ".mp3" completion of regular excodession completion of entire code

2.簡單案例

注,由於配置文件內容較多,為了讓大家看著方便,我們備份一下配置文件,打開一個新的配置文件。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15[root@nginx ~]# cd /etc/nginx/ [root@nginx nginx]# mv nginx.conf nginx.conf.proxy [root@nginx nginx]# cp nginx.conf.bak nginx.conf [root@nginx nginx]# vim /etc/nginx/nginx.conf server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; rewrite ^/bbs/(.*)$ http://192.168.18.201/forum/$1; } }

准備forum目錄與測試文件

1 2 3 4 5 6 7[root@web1 ~]# cd /var/www/html/ [root@web1 html]# ls index.html [root@web1 html]# mkdir forum [root@web1 html]# cd forum/ [root@web1 forum]# vim index.html

forum page!

測試一下

\

好了,下面我們來測試一下rewrite重寫。

3.重新加載一下配置文件

1 2 3 4[root@nginx 63]# service nginx reload nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful 重新載入 nginx: [確定]

4.測試一下

\

注,大家可以從圖中看出,status code 302指的是臨時重定向,那就說明我們rewrite重寫配置成功。大家知道302是臨時重定向而301是永久重定向,那麼怎麼實現永久重定向呢。一般服務器與服務器之間是臨時重定向,服務器內部是永久重定向。下面我們來演示一下永久重定向。

5.配置永久重定向

1 2 3 4 5 6 7 8 9 10 11 12[root@nginx nginx]# vim /etc/nginx/nginx.conf server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; rewrite ^/bbs/(.*)$ /forum/$1; } }

准備forum目錄與測試文件

1 2 3 4 5 6 7[root@nginx ~]# cd /usr/html/ [root@nginx html]# ls 50x.html index.html [root@nginx html]# mkdir forum [root@nginx html]# cd forum/ [root@nginx forum]# vim index.html

192.168.18.208 forum page

6.重新加載一下配置文件

1 2 3 4[root@nginx ~]# service nginx reload nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful 重新載入 nginx: [確定]

7.測試一下

\

注,大家從圖中可以看到,我們訪問bbs/是直接幫我們跳轉到forum/下,這種本機的跳轉就是永久重定向也叫隱式重定向。好了,rewrite重定向我們就說到這裡了,想要查詢更多關於重定向的指令請參考官方文檔。最後,我們來說一下讀寫分離。

if

語法:if (condition) { … }

默認值:none

使用字段:server, location

注意:在使用if指令之前請查看if is evil page並且盡量考慮用try_files代替。

判斷一個條件,如果條件成立,則後面的大括號內的語句將執行,相關配置從上級繼承。

可以在判斷語句中指定下列值:

一個變量的名稱;不成立的值為:空字符傳”“或者一些用“0”開始的字符串。

一個使用=或者!=運算符的比較語句。

使用符號~*和~模式匹配的正則表達式:

~為區分大小寫的匹配。

~*不區分大小寫的匹配(firefox匹配FireFox)。

!~和!~*意為“不匹配的”。

使用-f和!-f檢查一個文件是否存在。

使用-d和!-d檢查一個目錄是否存在。

使用-e和!-e檢查一個文件,目錄或者軟鏈接是否存在。

使用-x和!-x檢查一個文件是否為可執行文件。

正則表達式的一部分可以用圓括號,方便之後按照順序用$1-$9來引用。

示例配置:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /msie/$1 break; } if ($http_cookie ~* "id=([^;] +)(?:;|$)" ) { set $id $1; } if ($request_method = POST ) { return 405; } if (!-f $request_filename) { break; proxy_pass http://127.0.0.1; } if ($slow) { limit_rate 10k; } if ($invalid_referer) { return 403; } if ($args ~ post=140){ rewrite ^ http://example.com/ permanent; }

內置變量$invalid_referer用指令valid_referers指定。

return

語法:return code

默認值:none

使用字段:server, location, if

這個指令結束執行配置語句並為客戶端返回狀態代碼,可以使用下列的值:204,400,402-406,408,410, 411, 413, 416與500-504。此外,非標准代碼444將關閉連接並且不發送任何的頭部。

rewrite

語法:rewrite regex replacement flag

默認值:none

使用字段:server, location, if

按照相關的正則表達式與字符串修改URI,指令按照在配置文件中出現的順序執行。

可以在重寫指令後面添加標記。

如果替換的字符串以http://開頭,請求將被重定向,並且不再執行多余的rewrite指令。

尾部的標記(flag)可以是以下的值:

last - 完成重寫指令,之後搜索相應的URI或location。

break - 完成重寫指令。

redirect - 返回302臨時重定向,如果替換字段用http://開頭則被使用。

permanent - 返回301永久重定向。

注意如果一個重定向是相對的(沒有主機名部分),nginx將在重定向的過程中使用匹配server_name指令的“Host”頭或者server_name指令指定的第一個名稱,如果頭不匹配或不存在,如果沒有設置server_name,將使用本地主機名,如果你總是想讓nginx使用“Host”頭,可以在server_name使用“*”通配符(查看http核心模塊中的server_name)。例如:

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

但是如果我們將其放入一個名為/download/的location中,則需要將last標記改為break,否則nginx將執行10次循環並返回500錯誤。

1 2 3 4 5location /download/ { rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break; rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break; return 403; }

如果替換字段中包含參數,那麼其余的請求參數將附加到後面,為了防止附加,可以在最後一個字符後面跟一個問號:

1rewrite ^/users/(.*)$ /show?user=$1? last;

注意:大括號({和}),可以同時用在正則表達式和配置塊中,為了防止沖突,正則表達式使用大括號需要用雙引號(或者單引號)。例如要重寫以下的URL:

1/photos/123456

為:

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

則使用以下正則表達式(注意引號):

1rewrite "/photos/([0-9] {2})([0-9] {2})([0-9] {2})" /path/to/photos/$1/$1$2/$1$2$3.png;

如果指定一個“?”在重寫的結尾,Nginx將丟棄請求中的參數,即變量$args,當使用$request_uri或$uri&$args時可以在rewrite結尾使用“?”以避免nginx處理兩次參數串。

在rewrite中使用$request_uri將www.example.com重寫到example.com:

1 2 3 4server { server_name www.example.com; rewrite ^ http://example.com$request_uri? permanent; }

同樣,重寫只對路徑進行操作,而不是參數,如果要重寫一個帶參數的URL,可以使用以下代替:

1 2 3if ($args ^~ post=100){ rewrite ^ http://example.com/new-address.html? permanent; }

注意$args變量不會被編譯,與location過程中的URI不同(參考http核心模塊中的location)。

rewrite_log

語法:rewrite_log on | off

默認值:rewrite_log off

使用字段:server, location, if

變量:無

啟用時將在error log中記錄notice 標記的重寫日志。

set

語法:set variable value

默認值:none

使用字段:server, location, if

指令設置一個變量並為其賦值,其值可以是文本,變量和它們的組合。

你可以使用set定義一個新的變量,但是不能使用set設置$http_xxx頭部變量的值。

uninitialized_variable_warn

語法:uninitialized_variable_warn on|off

默認值:uninitialized_variable_warn on

使用字段:http, server, location, if

開啟或關閉在未初始化變量中記錄警告日志。

事實上,rewrite指令在配置文件加載時已經編譯到內部代碼中,在解釋器產生請求時使用。

這個解釋器是一個簡單的堆棧虛擬機,如下列指令:

1 2 3 4 5 6 7 8location /download/ { if ($forbidden) { return 403; } if ($slow) { limit_rate 10k; } rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;

將被編譯成以下順序:

1 2 3 4 5 6 7 8 9 10 11 12 13 14variable $forbidden checking to zero recovery 403 completion of entire code variable $slow checking to zero checkings of regular excodession copying "/" copying $1 copying "/mp3/" copying $2 copying ".mp3" completion of regular excodession completion of entire sequence

注意並沒有關於limit_rate的代碼,因為它沒有提及ngx_http_rewrite_module模塊,“if”塊可以類似”location”指令在配置文件的相同部分同時存在。

如果$slow為真,對應的if塊將生效,在這個配置中limit_rate的值為10k。

指令:

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

如果我們將第一個斜槓括入圓括號,則可以減少執行順序:

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

之後的順序類似如下:

1 2 3 4 5 6 7checking regular excodession copying $1 copying "/mp3/" copying $2 copying ".mp3" completion of regular excodession completion of entire code

2.簡單案例

注,由於配置文件內容較多,為了讓大家看著方便,我們備份一下配置文件,打開一個新的配置文件。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15[root@nginx ~]# cd /etc/nginx/ [root@nginx nginx]# mv nginx.conf nginx.conf.proxy [root@nginx nginx]# cp nginx.conf.bak nginx.conf [root@nginx nginx]# vim /etc/nginx/nginx.conf server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; rewrite ^/bbs/(.*)$ http://192.168.18.201/forum/$1; } }

准備forum目錄與測試文件

1 2 3 4 5 6 7[root@web1 ~]# cd /var/www/html/ [root@web1 html]# ls index.html [root@web1 html]# mkdir forum [root@web1 html]# cd forum/ [root@web1 forum]# vim index.html

forum page!

測試一下

\

好了,下面我們來測試一下rewrite重寫。

3.重新加載一下配置文件

1 2 3 4[root@nginx 63]# service nginx reload nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful 重新載入 nginx: [確定]

4.測試一下

\

注,大家可以從圖中看出,status code 302指的是臨時重定向,那就說明我們rewrite重寫配置成功。大家知道302是臨時重定向而301是永久重定向,那麼怎麼實現永久重定向呢。一般服務器與服務器之間是臨時重定向,服務器內部是永久重定向。下面我們來演示一下永久重定向。

5.配置永久重定向

1 2 3 4 5 6 7 8 9 10 11 12[root@nginx nginx]# vim /etc/nginx/nginx.conf server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; rewrite ^/bbs/(.*)$ /forum/$1; } }

准備forum目錄與測試文件

1 2 3 4 5 6 7[root@nginx ~]# cd /usr/html/ [root@nginx html]# ls 50x.html index.html [root@nginx html]# mkdir forum [root@nginx html]# cd forum/ [root@nginx forum]# vim index.html

192.168.18.208 forum page

6.重新加載一下配置文件

1 2 3 4[root@nginx ~]# service nginx reload nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful 重新載入 nginx: [確定]

7.測試一下

\

注,大家從圖中可以看到,我們訪問bbs/是直接幫我們跳轉到forum/下,這種本機的跳轉就是永久重定向也叫隱式重定向。好了,rewrite重定向我們就說到這裡了,想要查詢更多關於重定向的指令請參考官方文檔。最後,我們來說一下讀寫分離。

Copyright © Linux教程網 All Rights Reserved