ngx_http_rewrite_module
是Nginx服務(wù)器的重要模塊之一僚害,它一方面實現(xiàn)了URL的重寫功能就缆,另一方面為Nginx服務(wù)器提供反向代理服務(wù)提供了支持,同時思币,我們可以利用URL重寫功能完成一些其他工作一死,達到特殊的效果肛度。
域名跳轉(zhuǎn)
通過Rewrite功能可以實現(xiàn)一級域名跳轉(zhuǎn),也可以實現(xiàn)多節(jié)域名跳轉(zhuǎn)摘符。在server塊中配置Rewrite功能即可贤斜。
下面是幾個例子:
# 例1
...
server
{
listen 80;
server_name jump.myweb.name;
rewrite ^/ http://jump.myweb.info;
...
}
...
# 例2
...
server
{
listen 80;
server_name jump.myweb.name jump.myweb.info;
if ($host ~ myweb\.info) #注意正則表達式中對點號“.”要用“\”進行轉(zhuǎn)義
{
rewrite ^(.*) http://jump.myweb.name$1 permanent; #多域名跳轉(zhuǎn)
}
...
}
...
#例3
...
server
{
listen 80;
server_name jump1.myweb.name jump2.myweb.name;
if ($http_host ~* ^(.*)\.myweb\.name$)
{
rewrite ^(.*) http://jump.myweb.name$1; # 三級域名跳轉(zhuǎn)
break;
}
... #其他配置
}
... #其他配置
在上面的例子中展示了通過Rewrite功能完成域名跳轉(zhuǎn)的相關(guān)配置策吠。
在例1中逛裤,客戶端訪問http://jump.myweb.name時,URL將被Nginx服務(wù)器重寫為http://jump.myweb.info猴抹,客戶端得到的數(shù)據(jù)其實是由http://jump.myweb.info響應(yīng)的带族。
在例2中,客戶端訪問http://jump.myweb.info/reqsource時蟀给,URL將被Nginx服務(wù)器重寫為http://jump.myweb.name/reqsource蝙砌,客戶端得到的數(shù)據(jù)實際上是由http://jump.myweb.name響應(yīng)的。
在例3中跋理,客戶端訪問http://jump1.myweb.name/reqsource或者http://jump2.myweb.name/reqsource择克,URL都將被Nginx服務(wù)器重寫為http://jump.myweb.name/reqsource。
域名鏡像
鏡像網(wǎng)站是指將一個完全相同的網(wǎng)站分別放在幾個服務(wù)器上前普,并分別放置到幾個服務(wù)器上肚邢,并分別使用獨立的URL,其中一個服務(wù)器的網(wǎng)站叫做主站,其他的為鏡像網(wǎng)站骡湖。鏡像網(wǎng)站和主站沒有太大區(qū)別贱纠,或者可算是主站的后備。獎項網(wǎng)站可以保存網(wǎng)頁信息响蕴、歷史性數(shù)據(jù)谆焊、以防止丟失∑忠模可以通過鏡像網(wǎng)站提高網(wǎng)站在不同地區(qū)的響應(yīng)速度辖试。鏡像網(wǎng)站可以平衡網(wǎng)站的流量負載,可以解決網(wǎng)絡(luò)寬帶限制军拟、封鎖等剃执。
使用Nginx服務(wù)器的Rewrite功能可以輕松的實現(xiàn)域名鏡像的跳轉(zhuǎn)。其實原理很簡單懈息,就是在server塊中配置Rewrite功能肾档,將不同的鏡像URL重寫到指定的URL就可以了。以下是一個供大家參考的配置示例:
...
server
{
...
listen 80;
server_name mirror1.myweb.name;
rewrite ^(.*) http://jump1.myweb.name$1 last;
}
server
{
...
listen 81;
server_name mirror2.myweb.name;
rewrite ^(.*) http://jump2.myweb.name$1 last;
}
...
如果我們不想將整個網(wǎng)站做鏡像辫继,只想為某一個子目錄下的資源做鏡像怒见,我們可以在location塊中配置Rewrite功能,原理和上面是一樣姑宽。比如:
server
{
listen 80;
server_name jump.myweb.name;
location ^~ /source1
{
...
rewrite ^/source1(.*) http://jump.myweb.name/websrc2$1 last;
break;
}
location ^~ /source2
{
...
rewrite ^/source2(.*) http://jump.myweb.name/websrc2$1 last;
break;
}
...
}
... #其他配置
獨立域名
當一個網(wǎng)站包含多個板塊時遣耍,可以為其中的某些板塊設(shè)置獨立域名。其原理和設(shè)置某個子目錄鏡像的原理是相同的炮车。比如:
server
{
...
listen 80;
server_name bbs.myweb.com;
rewrite ^(.*) http://www.myweb.name/bbs$1 last;
break;
}
server
{
...
listen 81;
server_name home.myweb.name;
rewrite ^(.*) http://www.myweb.name/home$1 last;
break;
}
...
目錄自動添加“/”
如果網(wǎng)站設(shè)定了默認資源文件舵变,那么當客戶端使用URL訪問時可以不加具體的資源文件名稱。比如:在訪問www.myweb.name站點時瘦穆,應(yīng)該在瀏覽器地址欄中輸入“http://www.myweb.name/index.htm”這樣的URL纪隙,如果么我們設(shè)置了www.myweb.name站點的首頁為index.htm,那么直接在地址欄中輸入“http://www.myweb.name”即可訪問成功扛或,“/index.htm”可以省略不寫绵咱,現(xiàn)在大家基本上也都習(xí)慣了這種訪問方式。
當時如果請求的資源文件在二級目錄下熙兔,這樣的習(xí)慣可能會造成無法正常訪問資源悲伶。比如,在訪問http://www.myweb.name/bbs/index.htm時住涉,如果將URL省略為“http://www.myweb.name/bbs/”可以進行正常訪問麸锉,但是如果將URL寫為“http://www.myweb.name/bbs”,將末尾的斜杠“/”也省略了舆声,訪問就會出問題花沉。
也就是說,Nginx服務(wù)器訪問二級目錄時不加斜杠“/”無法訪問。但是我們不可能要求客戶端始終按照我們的要求在末尾添加斜杠“/”主穗,那么如果來解決這個問題呢泻拦?我們可以使用Rewrite功能為末尾沒有斜杠“/”的URL自動添加一個斜杠“/”:
server
{
...
listen 81;
server_name www.myweb.name;
location ^~ /bbs
{
...
if (-d $request_filename)
{
rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
}
}
}
在該示例中,我們使用if指令判斷請求的“/bbs”是目錄以后忽媒,匹配接收到的URI串争拐,并將各部分的值截取出來重新組裝,并在末尾添加斜杠“/”晦雨。注意應(yīng)該使用permannent標志指名是永久重定向該URI架曹。
目錄合并
搜索引擎優(yōu)化(Search Engine Optimization,SEO)是一種利用搜索引擎的搜索規(guī)則來提高目的網(wǎng)站在有關(guān)搜索引擎內(nèi)排名的方式。我們在創(chuàng)建自己的站點時闹瞧,我們通過一些措施有效提高搜索引擎優(yōu)化的程度绑雄,比如為網(wǎng)頁添加包含有有效關(guān)鍵字的標題,在正文中多使用有效關(guān)鍵字奥邮,制作網(wǎng)站導(dǎo)航時注意通用規(guī)則万牺,盡量避免大量的動態(tài)網(wǎng)頁,等等洽腺。目錄合并也是增強SEO的一個方法脚粟,它主要將多級目錄下的資源文件請求轉(zhuǎn)化為看上去是對目錄級數(shù)很少的資源的訪問。我們來看一個例子蘸朋,比如在網(wǎng)站中有這樣的一個網(wǎng)頁核无,它的路徑如下所示:
[root]/server/12/34/56/78/9.htm
網(wǎng)頁9.htm存在于第5級目錄下,如果要訪問這個資源文件藕坯,客戶端的URL要寫成http://www.myweb.name/server/12/34/56/78/9.htm团南,這非常不利于搜索引擎的搜索,同時也給客戶端的輸入帶來負擔炼彪。那么吐根,我們有沒有辦法讓URL的目錄級數(shù)“看上去”少一寫呢?通過Rewrite功能霹购,我們很容易就可以辦到佑惠。比如我們進行以下的配置:
server
{
...
listen 80;
server_name www.myweb.com
location ^~ /server
{
...
rewrite ~/server-([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)\.htm$ /server/$1/$2/$3/$4/$5.html last;
break;
}
}
那么朋腋,客戶端只要輸入“http://www.myweb.name/server-12-34-56-78-9.htm”即可訪問到9.htm這個資源文件了齐疙。這個URL是不是“看上去”簡單多了呢?這其實是充分利用了Rewrite指令支持正則表達式的特性旭咽。
防盜鏈
盜鏈是一種損害原有網(wǎng)站合法利益贞奋,給原網(wǎng)站所在服務(wù)器造成額外負擔的非法行為。要采取防盜鏈的措施穷绵,首先需要了解盜鏈的實現(xiàn)原理轿塔。
客戶端向服務(wù)器請求資源時,為了減少網(wǎng)絡(luò)帶寬,提高響應(yīng)時間勾缭,服務(wù)器一般不會一次將所有資源完整地傳回給客戶端揍障。比如在請求一個網(wǎng)頁時,首先會傳回該網(wǎng)頁的文本內(nèi)容俩由,當客戶端瀏覽器在解析文本的過程中發(fā)現(xiàn)有圖片存在時毒嫡,會再次向服務(wù)器發(fā)起對該圖片資源的請求,服務(wù)器將存儲的圖片資源再發(fā)送給客戶端幻梯。在這個過程中兜畸,如果該服務(wù)器上只包含了網(wǎng)頁的文本內(nèi)容,并沒有存放相關(guān)的圖片資源碘梢,而是將圖片資源連接到其他站點的服務(wù)器上確立咬摇,這就形成了盜鏈行為。在這種情況下煞躬,客戶端請求的圖片資源實際上來自于其他的服務(wù)器肛鹏。很明顯,盜鏈行為是一種對其他服務(wù)器不公平的行為恩沛。我們在搭建自己的站點時應(yīng)當有意識地采取防盜鏈措施龄坪。
要實現(xiàn)防盜鏈,需要了解HTTP協(xié)議中的請求頭部的Referer頭域和采用URL的格式表示訪問當前網(wǎng)頁或者文件的源地址复唤。通過該頭域的值健田,我們可以檢測到訪問目標資源的源地址。這樣佛纫,如果我們檢測到Referer頭域中的值并不是自己站點內(nèi)的URL妓局,就采取阻止措施,實現(xiàn)防盜鏈呈宇。但是好爬,需要提醒大家的時,由于Referer頭域中的值是可以被更改的甥啄,因此該方法不能夠完全阻止所有的盜鏈行為存炮。
知道了盜鏈行為的原理和防盜鏈的實現(xiàn)原理,我們就可以利用Nginx服務(wù)器的Rewrite功能實現(xiàn)防盜鏈了蜈漓。
Nginx的配置中有一個指令valid_referers穆桂,用來獲取Referer頭域中的值,并且根據(jù)該值的情況給Nginx全局變量$invalid_referer賦值融虽。如果Referer頭域中沒有符合valid_referers指令配置的值享完,$invalid_referer變量將會被賦值為1。valid_referers指令的語法結(jié)構(gòu)為:
valid_referers none | blocked | server_names | string ...;
- none有额,檢測Referer頭域不存在的情況般又。
- blocked彼绷,檢測Referer頭域的值被防火墻或者代理服務(wù)器刪除或偽裝的情況。這種情況下茴迁,該頭域的值不以“http://”或者“https://”開頭妄田。
- server_names顷编,設(shè)置一個或多個URL抚官,檢測Referer頭域的值是否是這些URL中的某個菩鲜。從Nginx 0.5.33以后支持使用通配符“*”。
有了valid_referers指令和$invalid_referer變量胳螟,就能通過Rewrite功能來實現(xiàn)防盜鏈昔馋。有兩種實現(xiàn)方案:一種是根據(jù)請求資源的資源類型,一種是根據(jù)請求目錄糖耸。
根據(jù)文件類型實現(xiàn)防盜鏈的一個配置實例如下:
server
{
...
listen 80;
server_name www.myweb.name;
location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip)$
{
...
valid_referers none blocked server_names *.myweb.name;
if ($invalid_referer)
{
rewrite ^/ http://www.myweb.com/images/forbidden.png;
}
}
}
在配置中秘遏,當有網(wǎng)絡(luò)連接對以gif、jpg嘉竟、png為后綴的圖片資源邦危,以swf、flv為后綴的媒體資源舍扰、以rar倦蚪、zip為后綴的壓縮存放資源發(fā)起請求時,如果檢測到Referer頭域中沒有符合valid_referers指令配置的值边苹,就將客戶單請求的URL重寫為http://www.myweb.com/images/forbidden.png陵且,這防止了非法盜鏈行為。當然我們也可以不重寫URL个束,直接返回HTTP錯誤狀態(tài)慕购,如403狀態(tài)。
根據(jù)請求目錄實現(xiàn)防盜鏈的一個配置示例如下:
server
{
...
listen 80;
server_name www.myweb.com
location /file/
{
...
root /server/file/;
valid_referers none blocked server_names *.myweb.com;
if ($invalid_referer)
{
rewrite ^/ http://www.myweb.com/images/forbidden.png;
}
}
}
...
其原理其實和根據(jù)文件類型實現(xiàn)防盜鏈的原理是一樣的茬底,只是在location塊的url變量上做了改變沪悲,對于請求服務(wù)器上[root]/server/file/目錄下資源采取了防盜鏈措施。