Nginx中rewrite(地址重定向)的深入剖析
目錄
- 一、rewrite語法
- 二、應(yīng)用場景
- 三、rewrite指定工作原理
- 四、flag 參數(shù)簡介
- 1、last
- 2、break
- 3、redirect
- 4、parmanent
- 五、示例
- 總結(jié)
一、rewrite語法
指令語法:rewrite regex replacement[flag]
默認(rèn)值:none
應(yīng)用位置:server、location、if
regex是PCRE 風(fēng)格的,如果regex匹配URI,那么URI就會被替換成replacement,replacement 就是新的URI。如果rewrite同一個上下文中有多個這樣的正則,匹配會依照rewrite指令出現(xiàn)的順序先后依次進行下去,匹配到一個之后并不會終止,而是繼續(xù)往下匹配,直到返回最后一個匹配上的為止。如果想要中止繼續(xù)往下匹配,可以使用第三個參數(shù)flag。
如果新URI字符中有關(guān)于協(xié)議的任何東西,比如http://或者https://等,進一步的處理就終止了,直接返回客戶端302。
如果返回的是30x,那么瀏覽器根據(jù)這個狀態(tài)碼和Location響應(yīng)頭再發(fā)起一次請求,然后才能得到想要的響應(yīng)結(jié)果。但是,如果不是返回30x狀態(tài)碼,那么跳轉(zhuǎn)就是內(nèi)部的,瀏覽器不做跳轉(zhuǎn)就能得到相應(yīng)。
rewrite是實現(xiàn)URL重定向的重要指令,他根據(jù)regex(正則表達式)來匹配內(nèi)容跳轉(zhuǎn)到replacement,結(jié)尾是flag標(biāo)記
示例:
rewrite ^/(.*) http://www.baidu.com/ permanent; # 匹配成功后跳轉(zhuǎn)到百度,執(zhí)行永久301跳轉(zhuǎn)
常用正則表達式:
rewrite的最后一項參數(shù)
二、應(yīng)用場景
- 調(diào)整用戶瀏覽的URL,看起來規(guī)范
- 為了讓搜索引擎收錄網(wǎng)站內(nèi)容,讓用戶體驗更好
- 網(wǎng)站更換新域名后
- 根據(jù)特殊的變量、目錄、客戶端進行跳轉(zhuǎn)
三、rewrite指定工作原理
rewrite模塊的指令有break, if, return, rewrite, set等。rewrite指令所執(zhí)行的順序如下:
首先在server上下文中依照順序執(zhí)行rewrite模塊指令;如果server中進行了rewrite重新,那么以新的URL發(fā)起內(nèi)部跳轉(zhuǎn),直接匹配location,不會再執(zhí)行server中的rewrite指令,然后
- 新URL直接匹配location
- 如果匹配上某個location,那么其中的rewrite模塊指令同樣依照順序執(zhí)行。
- 如果再次導(dǎo)致URL的rewrite,那么再一次進行內(nèi)部跳轉(zhuǎn)去匹配location,但跳轉(zhuǎn)的總次數(shù)不能超過10次。
四、flag 參數(shù)簡介
1、last
如果有l(wèi)ast參數(shù),那么停止處理任何rewrite相關(guān)的指令,立即用替換后的新URI開始下一輪的location匹配。
如果在location的rewrite也使用last,便會再次以新的URI重新發(fā)起內(nèi)部重定向,再次進行l(wèi)ocation匹配,而新的URI中極有可能和舊的URI一樣再次匹配到相同location中,這樣死循環(huán)發(fā)生了。當(dāng)循環(huán)到第10次時,Nginx會終止這樣無意義的循環(huán),并返回500錯誤。這點需要特別的注意。
2、break
停止處理任何rewrite的相關(guān)指令,就如同break 指令本身一樣。
last的break的相同點在于,立即停止執(zhí)行所有當(dāng)前上下文的rewrite模塊指令;不同點在于last參數(shù)接著用新的URI馬上搜尋新的location,而break不會搜尋新的location,直接用這個新的URI來處理請求,這樣能避免重復(fù)rewite。因此,在server上下文中使用last,而在location上下文中使用break。
3、redirect
replacement 如果不包含協(xié)議,仍然是一個新的的URI,那么就用新的URI匹配的location去處理請求,不會返回30x跳轉(zhuǎn)。但是redirect參數(shù)可以讓這種情況也返回30x(默認(rèn)302)狀態(tài)碼,就像新的URI包含http://和https://等一樣。這樣的話,瀏覽器看到302,就會再發(fā)起一次請求,真正返回響應(yīng)結(jié)果的就是這第二個請求。
4、parmanent
和redirect參數(shù)一樣,只不過直接返回301永久重定向
雖說URI有了新的,但是要拼接成完整的URL還需要當(dāng)前請求的scheme,以及由server_name_in_redirect和port_in_redirect指令決定的HOST和PORT.
還有一個比較有意思的應(yīng)用,就是如果replacement中包含請求參數(shù),那么默認(rèn)情況下舊URI中的請求參數(shù)也會拼接在replacement后面作為新的URI,如果不想這么做,可以在replacement的最后面加上?。
舉例說明:
rewrite ^/users/(.*)$ /show?user=$1? last;
這樣的新URI還是 /show?user=xxx
但如果不加問號:
rewrite ^/users/(.*)$ /show?user=$1 last;
得到的新URI就是/show?user=$1&xxx=xxx。其中xxx=xxx是舊URI所帶的請求參數(shù)。
五、示例
server { # 訪問 /last.html 的時候,頁面內(nèi)容重寫到 /index.html 中,并繼續(xù)后面的location匹配,瀏覽器地址欄URL地址不變 rewrite /last.html /index.html last; # 訪問 /break.html 的時候,頁面內(nèi)容重寫到 /index.html 中,并停止后續(xù)的匹配,瀏覽器地址欄URL地址不變; rewrite /break.html /index.html break; # 訪問 /redirect.html 的時候,頁面直接302定向到 /index.html中,瀏覽器地址URL跳為index.html rewrite /redirect.html /index.html redirect; # 訪問 /permanent.html 的時候,頁面直接301定向到 /index.html中,瀏覽器地址URL跳為index.html rewrite /permanent.html /index.html permanent; # 把 /html/*.html => /post/*.html ,301定向 rewrite ^/html/(.+?).html$ /post/$1.html permanent; # 把 /search/key => /search.html?keyword=key rewrite ^/search\/([^\/]+?)(\/|$) /search.html?keyword=$1 permanent; # 把當(dāng)前域名的請求,跳轉(zhuǎn)到新域名上,域名變化但路徑不變 rewrite ^/(.*) http://www.jd.com/$1 permanent; }
總結(jié)
到此這篇關(guān)于Nginx中rewrite(地址重定向)的文章就介紹到這了,更多相關(guān)Nginx rewrite地址重定向內(nèi)容請搜索以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持!
