文章目錄
前言
nginx通過ngx_http_rewrite_module模塊支持url重寫、支持if條件判斷,但不支持else(所以if判斷語句爲單分支)。
另外該模塊需要PCRE支持,應在編譯nginx時指定PCRE支持。根據相關變量重定向和選擇不同的配置,從一個location跳轉到另一個location,不過這樣的循環最多可以執行10次,超過後nginx將返回500錯誤。
同時,重寫模塊包含set指令,來創建新的變量並設其值,這在有些情景下非常有用的,如記錄條件標識、傳遞參數到其他location、記錄做了什麼等等。
一、Rewrite簡介
1.1 Rewrite跳轉場景
- URL看起來更加規範、合理
- 企業會將動態URL地址僞裝成靜態地址提供服務
- 網址更換新域名後,會讓舊的訪問網址
- 服務端某些業務跳轉
1.2 Rewrite跳轉實現
1.3 Rewrite實用場景
-
Nginx跳轉需求的實現方式有三種
① 使用 rewrite 進行匹配跳轉
② 使用 if 匹配全局變量後跳轉
③ 使用 location 匹配再跳轉
-
rewrite 可以放在 server{},if{}, location{} 段中
rewrite 不能放在 http {} 段中,因爲http段中指的是協議
-
對域名或參數字符串
① 使用if全局變量匹配
② 使用 proxy_pass 反向代理
1.4 常用正則表達式元字符
二、Rewrite命令
2.1 rewrite的語法
rewrite <regex> <replacement> [flag];
# 正則 跳轉後的內容 rewrite支持的flag標記
2.2 flag標記詳解
爬蟲:是一種按照一定的規則,自動地抓取萬維網信息的程序或者腳本(工具)
正則表達式:處理字符串的工具(按照各種規則進行處理,而正則表達式就是定義規則的工具)
三、location字段
3.1 location 分類
- location = patt {} [精準匹配]
- location patt {} [一般匹配 ]
- location ~ patt {} [正則匹配]
3.1.1 正則匹配的常用表達式
3.2 location 優先級
-
相同類型的表達式,字符串長的會優先匹配
-
按優先級排列如下:
= 類型
^~ 類型表達式
正則表達式 (和*)類型
常規字符串匹配類型,按前綴匹配
通用匹配(/),如果沒有其他匹配,任何請求都會匹配到
小結: location中 優先級從高到低 :‘=’ > ‘^~’ > ‘和*’ > 除通用匹配(/)的其他匹配形式 > ‘/’
3.3 比較 rewrite與 location
-
相同點
都能實現跳轉
-
不同點
rewrite 是在同一域名內更改獲取資源的路徑
location是對一類路徑做控制訪問或反向代理,還可以proxy_pass(反向代理) 到其他服務器
-
rewrite會寫在location中,執行順序
優先執行 server塊裏面的 rewrite指令
然後執行 location匹配
最後執行選定的 location中的 rewrite指令
3.4 location優先級規則
-
匹配某個具體文件
( location = 完整路徑)>( location ^~ 完整路徑)>( location ~* 完整路徑)>( location ~ 完整路徑)>( location完整路徑)>( location /)
-
用目錄做匹配訪問某個文件
( location = 目錄)>( location ^~ 目錄)>( location ~ 目錄)>
( location ~* 目錄)>( location 目錄)>( location /)
小結:匹配某個具體文件與用目錄做匹配訪問某個文件區別只有location ~* 與 location ~ 的優先級不同
示例:
location = / { #精確匹配 /,主機名後面不能帶任何字符串
[configuraion A ]
}
location / { #所有的地址都以/開頭,這條規則將匹配到所有請求,但正則和最長字符串會優先匹配
[configuraion B ]
}
location /documents/ { #匹配任何以/documents/開頭的地址,當後面的正則表達式沒有匹配到時,才起作用
[configuraion C ]
}
location ~ /documents/abc { #匹配任何以/documents/abc開頭的地址,當後面的正則表達式沒有匹配到時,纔會起作用
[configuraion D ]
}
location ^~ /images/ { #以/images/開頭的地址,匹配符合後,停止往下匹配
[configuraion E ]
}
location ~*\.(gif|jpg|gpeg)$ { #匹配所有以 gif, jpg或jpeg結尾的請求, images/下的圖片會被 [configuration E]處理,因爲^~的優先級更高
[configuraion F ]
}
location /images/abc { #最長字符匹配到 /images/abc,優先級最低
[configuraion G ]
}
location ~ /images/abc { #以/images/abc開頭的,優先級次之
[configuraion H ]
}
location /images/abc/1.html { #如果和正則 ~ images/abc/1.htm相比,正則優先級更高
[configuraion I ]
}
四、具體場景及配置(實驗部分)
實驗環境:
Ⅰ yum安裝nginx(或者使用手工編譯安裝)
Ⅱ 準備兩臺虛擬機
一臺centos7服務器 (IP地址爲192.168.181.140)
一臺win10主機 (IP地址爲192.168.181.136)
4.1 場景一:基於域名的跳轉
-
公司舊域名www.shuita.com,因業務需求有變更,需要使用新域名www.newshuita.com代替
條件一:不能廢除舊域名
條件二:從舊域名跳轉到新域名,且保持其參數不變
4.1.1 加載Nginx官方源
- ① 下載Nginx官方源
[root@localhost ~]# rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
引入Nginx官方源,實際上下載的是RPM包,下載後會自動加載到yum倉庫中,加載後纔可以使用yum 安裝Nginx
- ② 查看Nginx配置文件所在目錄
[root@localhost ~]# rpm -qc nginx
/etc/logrotate.d/nginx
/etc/nginx/conf.d/default.conf #Nginx主配置文件
/etc/nginx/fastcgi_params
/etc/nginx/koi-utf
/etc/nginx/koi-win
/etc/nginx/mime.types
/etc/nginx/nginx.conf
/etc/nginx/scgi_params
/etc/nginx/uwsgi_params
/etc/nginx/win-utf
/etc/sysconfig/nginx
/etc/sysconfig/nginx-debug
4.1.2 修改主配置文件
[root@localhost ~]# cd /etc/nginx/conf.d/
[root@localhost conf.d]# vim default.conf
server {
listen 80;
server_name www.shuita.com; #修改爲本服務器站點域名
------》wq
4.1.3 安裝、配置DNS
- ① 安裝、配置DNS解析
[root@localhost conf.d]# yum install bind -y
[root@localhost conf.d]# vim /etc/named.conf
listen-on port 53 { any; }; #修改爲any
allow-query { any; }; #修改爲any
[root@localhost conf.d]# vim /etc/named.rfc1912.zones
zone "shuita.com" IN { #舊域名
type master;
file "shuita.com.zone";
allow-update { none; };
};
zone "newshuita.com" IN { #新域名
type master;
file "newshuita.com.zone";
allow-update { none; };
};
#添加以上信息,將新、舊解析的域名配置完成
[root@localhost conf.d]# cd /var/named
[root@localhost named]# cp -p named.localhost shuita.com.zone
[root@localhost named]# vim shuita.com.zone
#刪除最後一行,添加以下內容
www IN A 192.168.181.140
[root@localhost named]# cp -p shuita.com.zone newshuita.com.zone
[root@localhost named]# ls
data dynamic named.ca named.empty named.localhost named.loopback newshuita.com.zone shuita.com.zone slaves
- ② 啓動DNS、Nginx服務
[root@localhost named]# systemctl start named
[root@localhost named]# systemctl start nginx
[root@localhost named]# systemctl stop firewalld.service #關閉防火牆
[root@localhost named]# setenforce 0 #關閉增強性安全功能
- ③ 使用win10虛擬機驗證
配置win10的網卡信息
訪問服務器站點
4.1.4 修改Nginx主配置文件
[root@localhost conf.d]# vim default.conf
- 重啓Nginx服務
[root@localhost conf.d]# systemctl restart nginx
4.1.5 訪問舊網址驗證
- 清理瀏覽器緩存、訪問舊網址
4.2 場景二:基於客戶端IP訪問跳轉
-
公司業務版本上線,所有IP訪問任何內容都顯示一個固定維護頁面,只有公司IP訪問正常
條件一:使用局域網的其他IP地址(非本服務器)訪問http://www.shuita.com域名和加參數請求maintenance.html頁面內容,狀態碼是200
條件二:使用http://www.shuita.com/test 帶參數訪問
4.2.1 修改Nginx主配置文件
- ① 刪除上一個跳轉訪問頁面的設置
- ② 修改Nginx主配置文件
[root@localhost conf.d]# vim default.conf
#設置是否合法的IP標記
set $rewrite true;
#合法IP打上標記,remote_addr(客戶端IP)地址設置爲本機地址
if ($remote_addr = "192.168.181.140"){
#匹配成功,則打上 false標記,允許繼續訪問
set $rewrite false;
}
#非法IP進行判斷打上標記
if ($rewrite = true){
#匹配成功,則跳轉至維護頁面
rewrite (.+) /maintenance.html;
}
#匹配標記進行跳轉站點
location = /maintenance.html {
#指向維護網頁的站點目錄
root /usr/share/nginx/html;
}
站點目錄:
yum安裝 Nginx 站點目錄爲:/usr/share/nginx/html
手工編譯安裝站點目錄:/usr/local/nginx/html
4.2.2 添加維護站點內容
[root@localhost conf.d]# cd /usr/share/nginx/html/
[root@localhost html]# ls
50x.html index.html
[root@localhost html]# vim maintenance.html #添加維護站點內容
<html>
<head>
<meta charset="utf-8">
<title>main</title>
</head>
<body>
<h1>Website maintenance~~~</h1>
<body>
</html>
-------》wq
- 重啓Nginx服務
[root@localhost named]# systemctl restart nginx
4.2.3 使用win10訪問站點
- 清理瀏覽器緩存、訪問站點
4.2.4 使用本機訪問站點
4.3 場景三:基於舊、新域名跳轉並加目錄
-
假如現在訪問的是http://ftp.shuita.com ,現在需要將這個域名下面的發帖都跳轉到http://www.shuita.com/ftp (ftp作爲目錄)
條件:保持域名跳轉後的參數不變
4.3.1 修改Nginx配置文件
-
① 將之前配置的內容刪除
-
② 修改Nginx主配置文件
-
③ 修改DNS區域數據配置文件
[root@localhost named]# vim shuita.com.zone
#將www修改爲ftp,否則客戶機則無法解析地址
ftp IN A 192.168.181.140
-------》wq
- ③ 指定DNS
[root@localhost named]# echo "nameserver 192.168.181.140" > /etc/resolv.conf
- ④ 重啓DNS、Nginx服務
[root@localhost named]# systemctl restart named
[root@localhost named]# systemctl restart nginx
4.3.2 訪問站點驗證
- 輸入http://ftp.shuita.com/post/a.html進行訪問
小結:主配置文件中設置的rewrite (.+) http://www.shuita.com/ftp$1中的**"$1"**包含着/post,我們在訪問的時候一定要加上post,否則配置文件中無法匹配到設置的內容
4.4 場景四:基於參數匹配跳轉
- 使用瀏覽器訪問http://www.shuita.com/100-(100|200)-100.html,會自動跳轉到http://www.shuita.com的頁面
4.4.1 修改Nginx主配置文件
- ① 修改主配置文件之前依然刪除之前修改的配置
[root@localhost named]# vim shuita.com.zone
www IN A 192.168.181.140 #將最後一行改回www
- 修改主Nginx主配置文件
[root@localhost named]# cd -
/etc/nginx/conf.d
[root@localhost conf.d]# vim default.conf
server {
listen 80;
server_name www.shuita.com; #改回www
#刪除原先設置的三行內容後添加以下內容
if ($request_uri ~ ^/100-(100|200)-(\d+).html$){
rewrite (.*) http://www.shuita.com permanent;
}
-------》wq
[root@localhost conf.d]# systemctl restart nginx
4.4.2 訪問站點測試
- 依然清除緩存後訪問站點
4.5 場景五:基於目錄下所有php文件跳轉
-
訪問http://www.shuita.com/upload/1.php 將跳轉到站點首頁
現實生活中,假如我將產品頁面複製給朋友,朋友訪問時也必須進行登錄後纔可以進行查看
4.5.1 修改Ngnix主配置文件
- 刪除之前的配置,再進行修改
[root@localhost conf.d]# vim default.conf
location ~* /upload/.*\.php$ {
rewrite (.+) http://www.shuita.com permanent;
}
--------》wq
[root@localhost conf.d]# systemctl restart nginx
4.5.2 訪問站點測試
- 清除緩存後訪問php頁面
4.6 場景六:基於最普通url請求跳轉
- 訪問一個具體的頁面跳轉到首頁
4.6.1 修改Nginx配置文件
[root@localhost conf.d]# vim default.conf
#基於場景五的配置,稍作修改即可
location ~* ^/abc/1.html {
rewrite (.+) http://www.shuita.com permanent;
}
-------》wq
[root@localhost conf.d]# systemctl restart nginx
- 重啓Nginx服務
[root@localhost conf.d]# vim default.conf
[root@localhost conf.d]# systemctl restart nginx
4.6.2 訪問站點測試
總結:
現網環境中,我們需要根據業務、環境要求在三種配置方式中選用合適的方法。配置本篇博客介紹的Nginx的Rwrite功能並不複雜,但是要對正則表達式很熟悉,知道如何去使用規則定位字符串及內容。