Nginx rewrite跳轉


一、Nginx跳轉需求的實現方式

二、常用的 Nginx 正則表達式

三、Rewrite

  ①Rewrite跳轉場景

  ②Rewrite 跳轉實現

  ③rewrite功能

  ④rewrite 執行順序

  ⑤rewrite 基本語法

四、location

  ①location 大致分類

  ②location 常用的匹配規則

  ③location 優先級

五、實驗

  ①、基於域名的跳轉

  ②、基於客戶端 IP 訪問跳轉

  ③、基於舊域名跳轉到新域名后面加目錄

  ④、基於參數匹配(多余的)的跳轉

  ⑤、基於目錄下所有 php 結尾的文件跳轉

  ⑥、基於最普通一條 url 請求的跳轉

 

 

一、Nginx跳轉需求的實現方式
使用rewrite進行匹配跳轉(主要匹配的是具體的路徑)
使用if匹配全局變量后跳轉
使用location匹配再跳轉(可以匹配后執行proxy_pass,將請求跳轉到其他服務上)

從功能看 rewrite 和 location 似乎有點像,都能實現跳轉,主要區別在於 rewrite 是在同一域,location 是對一類路徑做控制訪問或反向代理,還可以 proxy_pass 到其他機器。

 

二、常用的 Nginx 正則表達式
^ :匹配輸入字符串的起始位置
$ :匹配輸入字符串的結束位置
* :匹配前面的字符零次或多次。如“ol*”能匹配“o”及“ol”、“oll”
+ :匹配前面的字符一次或多次。如“ol+”能匹配“ol”及“oll”、“olll”,但不能匹配“o”
? :匹配前面的字符零次或一次,例如“do(es)?”能匹配“do”或者“does”,”?”等效於”{0,1}”
. :匹配除“\n”之外的任何單個字符,若要匹配包括“\n”在內的任意字符,請使用諸如“[.\n]”之類的模式
\ :將后面接着的字符標記為一個特殊字符或一個原義字符或一個向后引用。如“\n”匹配一個換行符,而“\$”則匹配“$”
\d :匹配純數字
\w :匹配字母或數字或下划線或漢字
\s :匹配任意的空白符
\b :匹配單詞的開始或結束
{n} :重復 n 次
{n,} :重復 n 次或更多次
{n,m} :重復 n 到 m 次
[] :定義匹配的字符范圍
[c] :匹配單個字符 c
[a-z] :匹配 a-z 小寫字母的任意一個
[a-zA-Z0-9] :匹配所有大小寫字母或數字
() :表達式的開始和結束位置 例如:(jpg|gif|swf|)
| :或運算符

 

三、Rewrite

①、Rewrite跳轉場景
1、調整用戶瀏覽的URL,看起來更規范,合乎開發及產品人員的需求。
2、為了讓搜索引擎搜尋網站內容及用戶體驗更好,企業會將動態URL地址偽裝成靜態地址提供服務。
3、網址換新域名后,讓舊的訪問跳轉到新的域名上。例如,訪問京東的 360buy.com 會跳轉到 jd.com。
4、服務端某些業務調整,比如根據特殊變量、目錄、客戶端的信息進行URL調整等。
URL 匹配和 重新跳轉新的URL
nginx rewrite(RUL)


②、Rewrite 跳轉實現
Nginx:通過ngx_http_rewrite_module 模塊支持URL重寫、支持if條件判斷,但不支持else
跳轉:從一個location跳轉到另一個location, 循環最多可以執行10次,超過后nginx將返回500錯誤
PCRE支持:perl兼容正則表達式的語法規則匹配
重寫模塊 set 指令:創建新的變量並設其值

③、rewrite功能
rewrite功能就是,使用nginx提供的全局變量或自己設置的變量,結合正則表達式和標記位實現URL重寫以及重定向。
比如:更換域名后需要保持舊的域名能跳轉到新的域名上、某網頁發生改變需要跳轉到新的頁面、網站防盜鏈等等需求。

rewrite只能放在server{ },location{ },if{ }中,並且默認只能對域名后邊的除去傳遞的參數外的字符串起作用,
例如 http://www.dabao.com/a/we/index.php?id=1&u=str 只對/a/we/index.php重寫。

④、rewrite 執行順序如下:
(1) 執行 server 模塊里面的rewrite 指令。
(2) 執行選定的 location 中的rewrite 指令。
(3) 執行選定的location中 if 中的rewrite指令

示例:
http {

  server {
         rewrite # 優先級1
  location ~*\.(jpg|gif|swf)$ {
                 rewrite # 優先級2
         valid_referers none blocked *.dog.com dog.com;
        if ( $invalid_referer ) {
                 rewrite ^/ http://www.dog.com/error.png; #優先級3}

                       }
               }
}

⑤、rewrite語法: rewrite <regex> <replacement> <flag>;
rewrite [flag];
regex:表示正則匹配規則。
replacement:表示跳轉后的內容。
flag:表示 rewrite 支持的 flag 標記。

####flag標記說明
last:本條規則匹配完成后,繼續向下匹配新的location URL規則,一般用在server和 if 中。
break:本條規則匹配完成即終止,不再匹配后面的任何規則,一般使用在location中。
redirect:返回302臨時重定向,瀏覽器地址會顯示跳轉后的URL地址。
permanent:返回301永久重定向,瀏覽器地址欄會顯示跳轉后的URL地址。

注:last和break最大的不同在於
- break 是終止當前location的rewrite檢測,而且不再進行location匹配
- last 是終止當前location的rewrite檢測,但會繼續重試location匹配並處理區塊中的rewrite規則

四、location

①、location 大致可以分為三類:
精准匹配:location = / {…} 示例: location = patt {} PS: 精確匹配字符串
一般匹配:location / {…} 示例: location patt {} PS: 只要包含patt的字符串即可
正則匹配:location ~ / {…} 示例: location ~ patt {} PS: 按照正則表達式的方式匹配

②、location 常用的匹配規則:
=:進行普通字符精確匹配,也就是完全匹配
^~:表示普通字符匹配。使用前綴匹配。如果匹配成功,則不再匹配其他 location
~:區分大小寫的匹配
~*:不區分大小寫的匹配
!~:區分大小寫的匹配取非
!~*:不區分大小寫的匹配取非
@:定義一個location,使用在內部定向的時候

③、location 優先級:
相同類型的表達式,字符串長的優先匹配

首先精確匹配 =
其次前綴匹配 ^~
其次是按文件中順序的正則匹配 ~或~*
然后匹配不帶任何修飾的前綴匹配,示例:/images/abc/
最后是交給 / 通用匹配

 

五、實驗

①、基於域名的跳轉

實驗場景:現在公司舊域名www.zyh.com有業務需求變更,需要使用新域名www.benet.com代替,但是舊域名不能廢除,需要跳轉到新域名上,而且后面的參數保持不變。

添加域名映射
vim /etc/hosts
192.168.10.20 www.benet.com www.zyh.com

 

 

 

創建日志目錄
mkdir -p /var/log/nginx/

修改配置文件
vim /usr/local/nginx/conf/nginx.conf

 

 

 

server {
listen 80;
server_name www.kgc.com; #域名修改

#charset koi8-r;

access_log /var/log/nginx/www.kgc.com-access.log; #開啟並對日志保存路徑進行修改

location / { #在原有location 位置插入
if ($host = 'www.kgc.com'){ #$host為rewrite全局變量,代表請求主機頭字段或主機名
rewrite ^/(.*)$ http://www.benet.com/$1 permanent; #$1為匹配的位置變量,即域名后邊得字符串,同時永久跳轉
}
root html;
index index.html index.htm;
}

systemctl restart nginx.service

驗證 訪問www.zyh.com 會跳轉到 www.benet.com

 

 

 

 

 

 ②、基於客戶端 IP 訪問跳轉

實驗場景:公司業務新版本上線,要求所有 IP 訪問任何內容都顯示一個固定維護頁面,只有公司 IP 192.168.10.20訪問正常。

vim /usr/local/nginx/conf/nginx.conf

 

 

access_log /var/log/nginx/www.kgc.com-access.log;
#設置是否是合法的IP標記
set $rewrite true; #設置變量$rewrite,變量形式為布爾值為true
#判斷是否為合法IP
if ($remote_addr = "192.168.10.20"){ #當客戶端IP為192.168.10.21時,將變量值設為flase,不進行重寫
set $rewrite false;
}
#除了合法IP,其它都是非法IP,進行重寫跳轉到維護頁面
if ($rewrite = true){ #布爾值表達式在不滿足false情況下,會匹配滿足true的location
rewrite (.+) /weihu.html; #重寫在訪問IP后邊插入/weihu.html,例如192.168.226.160/weihu.html
}
location = /weihu.html {
root /var/www/html; #頁面返回/var/www/html/weihu.html的內容
}

mkdir -p /var/www/html
echo '<h1>this is weihu web!</h1>' > /var/www/html/weihu.html
systemctl restart nginx.service

驗證:只有本公司主機可以正常訪問,其他ip訪問均為維護頁面

 ③、基於舊域名跳轉到新域名后面加目錄

當訪問的是 http://bbs.zyh.com/post/1.html 會自動跳轉到 http://www.benet.com/bbs/post/1.html

mkdir -p /usr/local/nginx/html/bbs/post
echo "<h1> this is 1.html </h1>" >> /usr/local/nginx/html/bbs/post/1.html
echo "192.168.10.21 bbs.zyh.com" >> /etc/hosts

 

 此時用瀏覽器訪問 http://bbs.zyh.com/post/1.html 會自動跳轉到 http://www.benet.com/bbs/post/1.html

 

 ④、基於參數匹配(多余的)的跳轉

現在訪問 http://www.zyh.com/100-(100|200)-100.html 會跳轉到 http://www.zyh.com的頁面

vim /usr/local/nginx/conf/nginx.conf

 

 systemctl restart nginx.service

access_log /var/log/nginx/www.zyh.com-access.log; #日志
#$request_uri 內置變量,表示URI,\d 純數字
if ($request_uri ~ ^/100-(100|200)-(\d+)\.html$){ #設置正則匹配,示例:http://www.zyh.com/100-100-1231.html
rewrite (.*) http://www.zyh.com permanent; #設置重寫
}

使用瀏覽器訪問 http://www.zyh.com/100-100-100.html 或 http://www.zyh.com/100-200-100.html會自動跳轉到 http://www.zyh.com頁面

 

 

⑤、基於目錄下所有 php 結尾的文件跳轉

要求訪問 http://www.zyh.com/upload/123.php 跳轉到首頁www.zyh.com (場景:注冊/登陸)

vim /usr/local/nginx/conf/nginx.conf

 

 systemctl restart nginx.service 

瀏覽器訪問 http://www.zyh.com/upload/123.php 跳轉到 http://www.zyh.com 首頁

 

 

⑥、基於最普通一條 url 請求的跳轉

要求訪問一個具體的頁面,如: http://www.zyh.com/abc/123.html,跳轉到首頁

vim /usr/local/nginx/conf/nginx.conf

 

 systemctl restart nginx.service

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM