您的位置:首頁>正文

nginx URL重寫

1.1 簡介

url重寫由ngx_http_rewrite_module模組提供, 預設會安裝, 但該模組功能的實現需要pcre。 URL重寫技術不僅要求掌握幾個指令的語法、熟悉簡單的規則運算式, 還需要儘量熟悉nginx的各個變數的意義, 熟悉的變數越多越好。 大多數需要用到的變數都是http_core模組提供的, 它們的意義參見官方手冊http_core內置變數。

rewrite模組主要有break、return、set、rewrite和if這5個指令。

break的作用是完成當前的作用集, 不再執行rewrite指令

return返回狀態碼。 可用的狀態碼有204/301/302/303/307/308/400/402-406/408/410-411/413/416/500-504。 return三種語法:

return code [text];return code URL;return URL;

set用於定義變數。 賦給變數的值可以是一個變數、文本及文本變數的組合(語法:set variable value;)

if用於設定判斷條件。 格式為if (condition) {}

rewrite用於設定URL重寫規則(語法:rewrite regex replacement [flag];)

1.2 if指令

if不支援嵌套, 不支援"&&"和"||"多目運算子。 語法為:

if (condition) {}

測試條件可以如下定義:

(1). 變數的比較可以使用"="和"!="運算子。

(2). 正則匹配可以使用"~"和"~*",前者表示區分大小寫的正則匹配, 後者表示不區分大小寫的匹配。

(3). 正則匹配可以在前面加上感嘆號"!~"和"!~*"表示取反, 即不匹配。

(4). "-f"和"!-f"判斷檔是否存在。

(5). "-d"和"!-d"判斷目錄是否存在。

(6). "-e"和"!-e"判斷檔或目錄或軟連結是否存在。

(7). "-x"和"!-x"判斷檔是否可執行。

if支援的規則運算式可以使用$1至$9來實現反向引用。

以下為幾個示例:

# 當使用IE流覽器訪問時, 重定向到/msie/目錄下的對應檔if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /msie/$1 break;}# 當http請求的方法為POST, 則直接返回405狀態碼, 即Method not Allowedif ($request_method = POST) { return 405;}# 當請求的資源檔不存在, 則直接退出當前匹配, 並代理至本機, 這種情況下由本機來提供服務, 如提供錯誤頁面if (!-f $request_filename) { break; proxy_pass http: //127.0.0.1;}# 當訪問的是longshuai.com下任意主機,
則重定向到www.longshuai.com主機下的對應目錄if ($http_host ~* "^(.*).longshuai.com$") { set $domain $1; rewrite ^(.*) http://www.longshuai.com/$domain/ break;}

上面最後一種URL重寫後的URL為一個新的主機名稱網站, 但使用URL重寫的效率比較低下, 遠不如直接為此網站獨立定義一個虛擬主機。 所以改寫為:

server { listen 80; server_name .longshuai.com; return 302 http://www.longshuai.com/$request_uri;}server { listen 80; server_name www.longshuai.com;}1.3 rewrite指令

rewrite可以寫在server段、location段和if段。 語法:

rewrite regexp replacement [flag]

如果replacement部分以"http://"或"https://"或"$schema"開頭, 則直接臨時重定向, 見下表中的redirect標記。

flag是標記。 有4種標記, 它們的作用如下表。

flag說明last停止處理當前上下文中的其他重寫模組指令, 並為重寫後的uri再次進行上下文的匹配break和break指令一樣, 都是停止處理當前上下文中的其他重寫模組指令redirect返回臨時重定向狀態碼302。 當replacement部分不是以"http://"或者"https://"或者"$schema"開頭的時候使用, "$schema"變數表示使用的是什麼協議permanent返回永久重定向狀態碼301

以上flag中,

last和break用來實現URL改寫, 此時流覽器中的位址不會改變, 但實際上在伺服器上訪問的資源和路徑已經改變了。 redirect和permanent用來實現URL跳轉, 流覽器中的位址會改變為跳轉後的位址。

在使用proxy_pass指令時要使用break標記。 last標記在本條rewrite規則執行完後, 繼續在當前上下文對重寫後的位址發起匹配請求, 而break則在本次匹配完成後停止再次匹配。 例如下面的兩條重寫規則。

rewrite "^/bbs/(.*)/images/(.*).jpg$" www.longshuai.com/bbs/$2/images/$1.jpg last;rewrite "^/bbs/(.*)/images/(.*).jpg$" www.longshuai.com/bbs/$2/images/$1.jpg break;

如果訪問的是www.longshuai.com/bbs/a/images/b.jpg則重寫後為www.longshuai.com/bbs/b/images/a.jpg, 但是重寫後的位址仍然可以匹配到規則^/bbs/(.*)/images/(.*).jpg$, 此時如果使用last標記, 則會再次進行重寫, 最終導致URL重寫迴圈, nginx默認支持10次迴圈, 然後返回500狀態碼。 而如果使用break標記, 則在重寫完成後不會再次匹配重寫。

例如, 下面的重寫示例將會使得任意以longshuai.com結尾的訪問重定向到www.longshuai.com。

server_name www.longshuai.com;rewrite (.*).longshuai.com www.longshuai.com permanent;

下面的重寫實例將使得www.longshuai.com/bbs/*的訪問都重定向到www.longshuai.com/forum/*。

server { listen 80; server_name www.longshuai.com; location /{ root /www/longshuai/; index index.html; rewrite "/bbs/(.*)" "/forum/$1" last; }}1.4 URL重寫和反向代理的區別

URL重寫和反向代理都能將請求轉發到其他主機上。 但它們有很大的區別。

1.URL重寫可以實現一些反向代理不能實現的轉發。

2.URL重寫可以實現流覽器位址改變。

3.反向代理更多的配合upstream實現負載均衡。 URL重寫無法直接通過轉發實現負載均衡。

4.還有很多其他的區別, 無需關心它們的區別, 當某種需求既可以URL重寫實現, 也可以反向代理實現, 隨便用一種方法即可。

(轉自博客園)

· 學IT, 就來中公優就業:http://www.ujiuye.com/

· 2017年【中公教育】特別推出2017年就業促進計畫, 500萬就業基金助你成為IT達人

詳情請戳http://www.ujiuye.com/zt/jycj/?wt.bd=bgz

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示