本篇主要對(duì)于Nginx中的Rewrite跳轉(zhuǎn)進(jìn)行講解。因?yàn)槟壳昂芏喙ぷ髑岸碎_發(fā)都會(huì)選擇使用Nginx作為反向代理服務(wù)器,但是平時(shí)業(yè)務(wù)需要難免碰到重寫URL,Nginx的Rewrite跳轉(zhuǎn)有什么使用場(chǎng)景呢?
- 公司更換域名需要訪問舊域名時(shí)跳轉(zhuǎn)到新域名
- 請(qǐng)求靜態(tài)文件跳轉(zhuǎn)到CDN
- 根據(jù)用戶設(shè)備不同跳轉(zhuǎn)到不同站點(diǎn)(pc端,移動(dòng)端)
不得不說的是Apache服務(wù)器規(guī)則庫很強(qiáng)大,做跳轉(zhuǎn)也很簡(jiǎn)單,但是Nginx使用Rewrite實(shí)現(xiàn)跳轉(zhuǎn)效率更高,所以這也是我們需要學(xué)習(xí)Nginx的Rewrite模塊的目的所在。Rewrite是Nginx的靜態(tài)重寫模塊,跳轉(zhuǎn)的使用場(chǎng)景有以下幾種情形:
- 可以改變用戶訪問的URL
- 可以將動(dòng)態(tài)URL偽裝成靜態(tài)URL提供服務(wù)
- 可以訪問舊域名時(shí)跳轉(zhuǎn)到新域名
- 可以根據(jù)變量,目錄,客戶端信息等跳轉(zhuǎn)不同的URL
Rewrite如何實(shí)現(xiàn)跳轉(zhuǎn)?
Nginx利用ngxhttprewrite_module模塊解析和處理rewrite請(qǐng)求。Rewrite用于實(shí)現(xiàn)URL重寫,其實(shí)有點(diǎn)類似于重定向功能,可以將用戶的請(qǐng)求重寫至別的目錄,在一定程度上提高了網(wǎng)站安全性。Rewrite支持if條件判斷,但不支持else判斷。而且Rewrite需要PCRE支持,一次重定向最多可以跳轉(zhuǎn)10次,超過10次將返回500錯(cuò)誤。Rewrite模塊包含set命令,可以創(chuàng)建變量用來記錄條件標(biāo)識(shí)或者傳遞變量到其他的Location中。Rewrite實(shí)際上就是使用Nginx已有的全局變量或者通過set命令設(shè)置的變量結(jié)合正則表達(dá)式實(shí)現(xiàn)URL重寫。
Rewrite使用場(chǎng)景
在Nginx中使用Rewrite實(shí)現(xiàn)跳轉(zhuǎn)有以下三種場(chǎng)景:
- 直接用Rewrite進(jìn)行匹配跳轉(zhuǎn)
- 使用if匹配全局變量進(jìn)行跳轉(zhuǎn)
- 使用location匹配再進(jìn)行跳轉(zhuǎn)
所以說rewrite語句只允許放在server{ },if{ },location{ }中。接下來我們先看看if指令。
if指令
if指令用于條件匹配判斷,根據(jù)判斷結(jié)果選擇不同的Nginx配置,在server或location中配置。Nginx中的if指令只支持單重判斷,不支持多重判斷。我們簡(jiǎn)單看個(gè)例子:
location /test{
index index.html;
if ( $scheme = http ){
rewrite / https://www.niyueling.cn permanent;
}
if ($scheme = https ){
echo "if ---> $scheme";
}
> }
location上篇文章講過了,這里不再細(xì)講,接下來我們看下rewrite語法.
rewrite語法
- rewrite regex replacement [flag]
rewrite將用戶請(qǐng)求的URL基于正則表達(dá)式regex進(jìn)行檢查,匹配到時(shí)將其替換為正則表達(dá)式對(duì)應(yīng)的新的URL。若在同一級(jí)配置模塊中存在多個(gè)rewrite規(guī)則,則會(huì)自頂向下檢查。replacement則為跳轉(zhuǎn)后的內(nèi)容。[flag]作為標(biāo)識(shí)符用于控制循環(huán)機(jī)制,如果替換后的URL是以http或者h(yuǎn)ttps開頭,則會(huì)直接301永久重定向。
flag參數(shù)介紹
rewrite語句有四種flag狀態(tài):redirect、permanent、break、last。前兩種屬于客戶瀏覽器重新發(fā)起對(duì)新地址的請(qǐng)求,后兩種是在WEB服務(wù)器內(nèi)部實(shí)現(xiàn)跳轉(zhuǎn)。
- redirect #臨時(shí)重定向,重寫完成后以臨時(shí)重定向方式直接返回重寫后生成的新URL給客戶端,有客戶端重新發(fā)起請(qǐng)求,使用相對(duì)路徑,http://或https://開頭,狀態(tài)碼:302
- permanent #永久重定向,以永久重定向的方式直接返回重寫后生成的新URL給客戶端,由客戶端重新發(fā)起新的請(qǐng)求,狀態(tài)碼:301
- last #重寫完成后停止對(duì)當(dāng)前l(fā)ocation中后續(xù)的其他重寫操作,而后對(duì)新的URL啟動(dòng)新一輪重寫檢查,不建議在location中使用
- break #重寫完成后停止對(duì)當(dāng)前URL在當(dāng)前l(fā)ocation中后續(xù)的其他重寫操作,而后直接跳轉(zhuǎn)至重寫規(guī)則匹配塊之后的其他配置;結(jié)束循環(huán),建議在location中使用
rewrite語法講完了我們可以一起來看看如何實(shí)現(xiàn)幾種方式跳轉(zhuǎn):
(1) 在location中將舊域名永久重定向到新域名
location / {
root /data/html;
index index.html;
rewrite / http://www.niyueling.cn permanent;
}
這里有必要提下臨時(shí)重定向與永久重定向的區(qū)別:
臨時(shí)重定向不會(huì)緩存新域名的解析記錄,但是永久重定向會(huì)緩存新域名的解析記錄。
(2) http自動(dòng)跳轉(zhuǎn)https
有時(shí)候公司項(xiàng)目需要,會(huì)要求整個(gè)網(wǎng)站皆使用https,這時(shí)候?yàn)榱擞脩趔w驗(yàn),我們需要在用戶訪問http站點(diǎn)的時(shí)候自動(dòng)跳轉(zhuǎn)到https站點(diǎn)中。
location / {
root /opt/blog;
index index.html;
if ( $scheme = http ){
rewrite / https://www.niyueling.cn permanent;
}
}
上面配置其實(shí)就是如果用戶請(qǐng)求協(xié)議為http的時(shí)候使用rewrite跳轉(zhuǎn)到對(duì)應(yīng)的https站點(diǎn)。但是if語句不能去掉,否則就會(huì)陷入死循環(huán)。
(3) 如果用戶請(qǐng)求URL不存在跳轉(zhuǎn)首頁
location / {root /opt/blog;index index.html;if ( !-f $request_filename ){rewrite (.*) http://www.niyueling.cn;}}
(4) 實(shí)現(xiàn)防盜鏈
防盜鏈實(shí)際上是基于前端攜帶的referer實(shí)現(xiàn),referer可以記錄用戶從哪個(gè)界面跳轉(zhuǎn)而來的標(biāo)志信息。Nginx可以通過ungxhttpreferrer_module模塊來檢查請(qǐng)求的referer信息是否有效實(shí)現(xiàn)防盜鏈功能
location ^~ /test {root /opt/blog;index index.html;validreferers none blocked servernames .niyueling.cn www.niyueling.api.online.test/v1/hostlist ~.google. ~.baidu.; #定義有效的refererif ($invalid_referer) { #假如是使用其他的無效的referer訪問:return 403; #返回狀態(tài)碼403}}
如果喜歡我的文章,歡迎關(guān)注我的個(gè)人公眾號(hào)
本文由博客一文多發(fā)平臺(tái) https://openwrite.cn?from=article_bottom 發(fā)布!