nginx rewrite功能使用場景分析
大家在瀏覽某些網(wǎng)站的時候,有沒有發(fā)現(xiàn),當(dāng)輸入:www.abc.com或者www.abcd.com的時候,頁面均能正常顯示www.abc.com的主頁內(nèi)容。這就是nginx rewrite的一個使用場景。
rewrite簡介
rewrite是Nginx服務(wù)器提供的一個重要基本功能,主要作用用來實現(xiàn)URL地址重寫
rewrite功能實現(xiàn)依賴于pcre的支持,因此在編譯安裝Nginx服務(wù)器之前,需安裝pcre庫(nginx使用ngx_http_rewrite_module模塊來解析和處理Rewrite功能的相關(guān)配置)
在真正了解rewrite的使用之前,有必要全面系統(tǒng)學(xué)習(xí)下rewrite相關(guān)的指令和語法使用,下面來逐一了解下吧
Rewrite規(guī)則與指令
set指令
該指令用來設(shè)置一個新的變量。
- variable,變量名,該變量名要用"$"作為變量的第一個字符,且不能與Nginx服務(wù)器預(yù)設(shè)的全局變量同名;
- value:變量值,可以是字符串、其他變量或者變量的組合等;
一個簡單的案例
server { listen 8081; server_name localhsot; location /server { set $name zhangsan; set $age 19; default_type text/plain; return 200 $name=$age; } }
重啟nginx服務(wù),然后瀏覽器訪問觀察下效果
下面列舉了Rewrite常用全局變量
這些變量可以在使用過程中結(jié)合自身的業(yè)務(wù)靈活選擇使用
變量 | 說明 |
---|---|
$args | 變量中存放了請求URL中的請求指令。如http://IP:8080?arg1=value1&args2=value2中 的"arg1=value1&arg2=value2",功能和$query_string一樣 |
$http_user_agent | 變量存儲了用戶訪問服務(wù)的代理信息(如果通過瀏覽器訪問,記錄的是瀏覽器的相關(guān)版本信息) |
$host | 變量存儲的是訪問服務(wù)器的server_name值 |
$document_uri | 變量存儲了當(dāng)前訪問地址的URI。比如http://IP/server?id=10&name=zhangsan中的"/server",功能和$uri一樣 |
$document_root | 變量存儲的是當(dāng)前請求對應(yīng)location的root值,如果未設(shè)置,默認(rèn)指向Nginx自帶html目錄所在位置 |
$content_length | 變量存儲的是請求頭中的Content-Length的值 |
$content_type | 變量存儲的是請求頭中的Content-Type的值 |
$http_cookie | 變量存儲的是客戶端的cookie信息,可以通過add_header Set-Cookie’cookieName=cookieValue’來添加cookie數(shù) 據(jù) |
$limit_rate | 變量中存儲的是Nginx服務(wù)器對網(wǎng)絡(luò)連接速率的限制,也就是Nginx配置中對limit_rate指令設(shè)置的值,默認(rèn)是0,不限制 |
$remote_addr | 變量中存儲的是客戶端的IP地址 |
$remote_port | 變量中存儲了客戶端與服務(wù)端建立連接的端口號 |
$remote_user | 變量中存儲了客戶端的用戶名,需要有認(rèn)證模塊才能獲取 |
$scheme | 變量中存儲了訪問協(xié)議 |
$server_addr | 變量中存儲了服務(wù)端的地址 |
$server_name | 變量中存儲了客戶端請求到達(dá)的服務(wù)器的名稱 |
$server_port | 變量中存儲了客戶端請求到達(dá)服務(wù)器的端口號 |
$server_protocol | 變量中存儲了客戶端請求協(xié)議的版本,比如"HTTP/1.1" |
$request_body_file | 變量中存儲了發(fā)給后端服務(wù)器的本地文件資源的名稱 |
$request_method | 變量中存儲了客戶端的請求方式,比如"GET","POST"等 |
$request_filename | 變量中存儲了當(dāng)前請求的資源文件的路徑名 |
$request_uri | 變量中存儲了當(dāng)前請求的URI,并且攜帶請求參數(shù),比如http://IP/server?id=10&name=zhangsan中的"/server?id=10&name=zhangsan名 |
我們來隨機測試下幾個指令的使用吧
$args
server { listen 8081; server_name localhsot; location /server { set $name zhangsan; set $age 19; default_type text/plain; return 200 $name=$age=$args; } }
$http_user_agent
其他的指令有興趣的同學(xué)可以自行嘗試,下面使用這些指令完成一個需求
自定義日志輸出格式,將請求的日志輸出到自定義的日志中
具體配置如下:
log_format main '$remote_addr - $request - $status - $request_uri - $http_user_agent'; server { listen 8081; server_name localhsot; location /server { access_log logs/access-server.log main; set $name zhangsan; set $age 19; default_type text/plain; return 200 $name=$age=$args=$http_user_agent; } }
通過這種方式,就可以實現(xiàn)自定義請求的相關(guān)參數(shù)輸出到自定義的日志文件中
if指令
該指令用來支持條件判斷,并根據(jù)條件判斷結(jié)果選擇不同的Nginx配置
condition為判定條件,可以支持以下寫法:
1)變量名稱,如果變量名對應(yīng)的值為空或者是0,if都判斷為false,其他條件為true
if ($param) { }
location /testif { set $username 'zhangsan'; default_type text/plain; if ($username){return 200 success; } return 200 'params is empty'; }
2) 使用"=“和”!="比較變量和字符串是否相等,滿足為true,不滿足為false
if ($request_method = POST) { return 405; 3 }
注意:此處和Java不一樣的是字符串不需加引號
3)使用正則表達(dá)式對變量匹配
- 匹配成功返回true,否則返回false;
- 變量與正則表達(dá)式之間使用"“,”“,”!“,”!"來連接;
- “~” 代表匹配正則表達(dá)式過程中區(qū)分大小寫;
- "~*"代表匹配正則表達(dá)式過程中不區(qū)分大小寫;
- "!“和”!*"剛好和上面取相反值,如果匹配上返回false,匹配不上返回true;
if ($http_user_agent ~ MSIE) { #$http_user_agent的值中是否包含MSIE字符串,如果包含返回 true }
注意:正則表達(dá)式字符串一般不需要加引號,但是如果字符串中包含"}“或者是”;"等字符時,就需要把引號加上
if ($http_user_agent ~ Safari){return 200 Chrome; }
4)判斷請求文件是否存在使用"-f"和"!-f"
- 當(dāng)使用"-f"時,如果請求的文件存在返回true,不存在返回false;
- 當(dāng)使用"!f"時,如果請求文件不存在,但該文件所在目錄存在返回true,文件和目錄都不存在返回false,如果文件存在返回false;
if (-f $request_filename){ #判斷請求的文件是否存在 } if (!-f $request_filename){ #判斷請求的文件是否不存在 }
案例展示
location /file { root html; default_type text/html; if (!-f $request_filename){return 200 '<h1>not find file</h1>'; } }
當(dāng)訪問目錄下不存在的文件時,將會看到如下的異常返回
5) 判斷請求的目錄是否存在使用"-d"和"!-d"
- 當(dāng)使用"-d"時,如果請求的目錄存在,if返回true,如果目錄不存在則返回false;
- 當(dāng)使用"!-d"時,如果請求的目錄不存在但該目錄的上級目錄存在則返回true,該目錄和它上級目錄都不存在則返回false,如果請求目錄存在也返回false;
6) 判斷請求的目錄或者文件是否存在使用"-e"和"!-e"
- 當(dāng)使用"-e",如果請求的目錄或者文件存在時,if返回true,否則返回false;
- 當(dāng)使用"!-e",如果請求的文件和文件所在路徑上的目錄都不存在返回true,否則返回false;
7) 判斷請求的文件是否可執(zhí)行使用"-x"和"!-x"
- 當(dāng)使用"-x",如果請求的文件可執(zhí)行,if返回true,否則返回false;
- 當(dāng)使用"!-x",如果請求文件不可執(zhí)行,返回true,否則返回false; break指令
該指令用于中斷當(dāng)前相同作用域中的其他Nginx配置。與該指令處于同一作用域的Nginx配置中,位于它前面的指令配置生效,位于后面的指令配置無效
location /{ if ($param){ set $id $1; break; limit_rate 10k; } }
案例演示
location /break { default_type text/plain; set $username MIKE; if ($args){set $username JIM;break;set $username JODAN; } return 200 $username; }
return指令
該指令用于完成對請求的處理,直接向客戶端返回響應(yīng)狀態(tài)代碼。在return后的所有Nginx配置都是無效的
- code,為返回給客戶端的HTTP狀態(tài)代理??梢苑祷氐臓顟B(tài)代碼為0~999的任意HTTP狀態(tài)代理;
- text:為返回給客戶端的響應(yīng)體內(nèi)容,支持變量的使用;
- URL:為返回給客戶端的URL地址;
location /return { default_type application/json; return 200 '{id:1,name:jike}'; }
rewrite指令
該指令通過正則表達(dá)式的使用來改變URI??梢酝瑫r存在一個或者多個指令,按照順序依次對URL進(jìn)行匹配和處理
URL和URI的區(qū)別
- URI:統(tǒng)一資源標(biāo)識符
- URL:統(tǒng)一資源定位符
- regex,用來匹配URI的正則表達(dá)式;
- replacement:匹配成功后,用于替換URI中被截取內(nèi)容的字符串。如果該字符串是以"http://"或者"https://"開頭的,則不會繼續(xù)向下對URI進(jìn)行其他處理,而是直接返回重寫后的URI給客戶端;
- flag:用來設(shè)置rewrite對URI的處理行為,可選值有如下
last break redirect permanent
last : 終止繼續(xù)在本location中處理接收到的URI,并將此處重寫的URI作為一個新的URI,使用各location塊進(jìn)行處理。該標(biāo)志將重寫的URI重寫在server塊中執(zhí)行,為重寫后的URI提供了轉(zhuǎn)入到其他location塊的機會;
break : 將此處重寫的URI作為一個新的URI,在本塊中繼續(xù)處理,該標(biāo)志重寫后的地址在當(dāng)前的location塊中執(zhí)行,不會將新的URI轉(zhuǎn)向其他的location塊;
redirect : 將重寫后的URI返回給客戶端,狀態(tài)碼為302,指明是臨時重定向URI,主要用在replacement變量不是以 “http://”或“https://”開頭的情況;
redirect : 將重寫后的URI返回給客戶端,狀態(tài)碼為302,指明是臨時重定向URI,主要用在replacement變量不是以 “http://”或“https://”開頭的情況;
permanent : 將重寫后的URI返回給客戶端,狀態(tài)碼為301,指明是臨時重定向URI,主要用在replacement變量不是以 “http://”或“https://”開頭的情況;
示例1
location /rewirte { rewrite ^/rewrite/url\w*$ https://www.baidu.com; rewrite ^/rewrite/(test)/\w*$ /$1; rewrite ^/rewrite/(hello)/\w*$ /$1; } location /test { default_type text/plain; return 200 "hello success"; }
示例2
location /rewirte { rewrite ^/rewrite/url\w*$ https://www.baidu.com; rewrite ^/rewrite/(test)/\w*$ /$1 last; rewrite ^/rewrite/(hello)/\w*$ /$1 last; } location /test { default_type text/plain; return 200 "hello success"; }
rewrite_log指令
該指令配置是否開啟URL重寫日志的輸出功能
開啟后,URL重寫的相關(guān)日志將以notice級別輸出到error_log指令配置的日志文件匯總
location /rewirte { rewrite_log on; error_log logs/error.log notice; rewrite ^/rewrite/url\w*$ https://www.baidu.com; rewrite ^/rewrite/(test)/\w*$ /$1 last; rewrite ^/rewrite/(hello)/\w*$ /$1 last; }
一、rewrite配置域名跳轉(zhuǎn)
有很多大型網(wǎng)站,在起步的時候,比如域名為 : www.haoyijia.com,但是域名太長所帶來的問題就是不方便記憶,于是后面改成 www.hyj.com,問題是,一些老用戶之前一直習(xí)慣了那個長域名,如何在老用戶輸入長域名的時候仍然可以跳轉(zhuǎn)到新的短域名上呢?就可以考慮使用rewrite的功能;下面在本地做一下模擬。
配置步驟:
1、準(zhǔn)備兩個域名
這里我直接在本地模擬2個域名,通過在本地的hosts文件配置下就可以了
2、配置nginx.conf文件
server { listen 80; server_name www.zcy.com www.zhangcongyi.com; rewrite ^/ http://www.jd.com permanent; }
重啟nginx服務(wù),瀏覽器訪問:www.zcy.com 或者www.zhangcongyi.com,觀察效果
二、rewrite配置獨立域名
一個完整的項目包含多個模塊,比如購物網(wǎng)站有商品商品搜索模塊、商品詳情模塊、購物車模塊等,那么我們?nèi)绾螢槊恳粋€模塊設(shè)置獨立的域名。
server{ listen 80; server_name search.hm.com; rewrite ^(.*) http://www.hm.com/bbs$1 last; } server{ listen 81; server_name item.hm.com; rewrite ^(.*) http://www.hm.com/item$1 last; } server{ listen 82; server_name cart.hm.com; rewrite ^(.*) http://www.hm.com/cart$1 last; }
本地的hosts文件添加如下配置
重啟nginx服務(wù),可以在瀏覽器訪問下觀察效果如何
三、rewrite配置目錄合并
搜索引擎優(yōu)化(SEO)是一種利用搜索引擎的搜索規(guī)則,來提供目的網(wǎng)站的有關(guān)搜索引擎內(nèi)排名的方式;
我們在創(chuàng)建自己的站點時,可以通過很多種方式有效提供搜索引擎優(yōu)化的程度,其中有一項就包含URL的目錄層級一般不要超過三層,否則的話不利于搜索引擎的搜索也給客戶端的輸入帶來了負(fù)擔(dān);
但是將所有的文件放在一個目錄下又會導(dǎo)致文件資源管理混亂,并且訪問文件的速度也會隨著文件增多而慢下來,這兩個問題是相互矛盾的,使用rewrite就可以解決上述問題;
舉例,網(wǎng)站中有一個資源文件的訪問路徑時,比如訪問:/server/11/22/33/44/20.html,也就是說20.html存在于第5級目錄下,如果想要訪問該資源文件,客戶端的URL地址就要寫成http://www.web.name/server/11/22/33/44/20.html;
server { listen 80; server_name www.web.com; location /server{ root html; } }
但是這個是非常不利于SEO搜索引擎優(yōu)化的,同時客戶端也不好記,使用rewrite我們可以進(jìn)行如下配置:
server { listen 80; server_name www.web.com; location /server{ rewrite ^/server-([0-9]+)-([0-9]+)-([0-9]+)- ([0-9]+)\.html$ /server/$1/$2/$3/$4/$5.html last; } }
到此這篇關(guān)于nginx rewrite功能使用的文章就介紹到這了,更多相關(guān)nginx rewrite使用內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。