常用的nginx正規表達式
^ :比對輸入字元串的開頭
$:比對輸入字元串的結尾
*:比對前面的字元零次或者多次
+:比對前面的字元一次或者多次
?:比對前面的字元零次或者一次
. :比對除"\n"外的任何一個單詞。如果要比對"\n"的字元串,請使用[.\n]之類的模式
:将後面的接着的字元标記為一個特殊字元或者一個原義字或者一個向後引用
\d :比對純數字[0-9]、\s: 空白符 \w:任意單次包括下劃線[A-Za-z0-9]
{n}:重複n次
{n,} :重複n次或者更多
{n,m}:重複n到m此
[ ] :定義比對的字元換位
[ c ] : 比對單個字元c
[a-z]:比對a-z任意小寫字元一個
[A-Za-z0-9]:比對所有大小寫字元或者數字
() :表達的開始和結束的位置
| :或運算符
從功能上看,rewrite和location似乎有點像,都能實作跳轉,主要差別在于rewrite是在同一域名下更改擷取資源途徑的路徑,而location是一對類路做控制通路或者反向代理,還可以proxy_pass到其他機器
rewrite對通路的域名内的URL路徑位址重寫
location對通路的路徑做通路控制或者代理轉發
Location
location大緻可以分為三類:
精準比對:locayion = / {...}
一般比對: location / {...} #最長比對原則(如果有長度最長的屁比對項的話,就會選擇最長的那個)
正則比對: location ~ / {...}
location常用比對選項:
= :進行普通字元的精準比對,也就是完全比對
^~ :進行普通字元精确比對,也就是完全比對。
~ :區分大小寫的比對。
~* :不區分大小寫的比對。
!~* :!~:區分大小寫的比對取非。
!~* :不區分大小寫的比對取非。
location比對的優先級
首先是精準比對 =
其次是字首比對 (比對到後就停止搜尋,直接采用這一條!)
其次是按照檔案中的順序的正則比對, ~或者 ~*
然後比對不帶任何修飾的字首比對(一般比對)
最後是交給 "/" (通用比對)
location示例說明:
1、location = / {}
=.為精确比對/,主機名後面不能帶任何字元串,比如通路/和/data, 則/比對,/data 不比對再比如location = /abc, 則隻比對/abc,/abc/或/abcd不比對。若location /abc, 則即比對/abc、/abcd/ 同時也比對/abc/.
(2) location / {}
因為所有的位址都以1開頭,是以這條規則将比對到所有請求比如通路/和/data則1比對, /data 也比對,但若後面是正規表達式會和最長字元串優先比對(最長比對)
(3) location /documents/ {}比對任何以/documents/ 開頭的位址,比對符合以後,還要繼續往下搜尋其它location隻有其它location後 面的正規表達式沒有比對到時,才會采用這一條
(4) location /documents/abc {}比對任何以/documents/abc 開頭的位址,比對符合以後,還要繼續往下搜尋其它location隻有其它location後 面的正規表達式沒有比對到時,才會采用這一條
(5) location ^~ /images/ {}
比對任何以/images/ 開頭的位址,比對符合以後,停止往下搜尋正則,采用這一條
(6) location ~* . (gifljpg ljpeg)$ {}
比對所有以gif、jpg或jpeg結尾的請求然而,所有請求/images/ 下的圖檔會被location ^~ /images/ 處理,因為^~的優先級更高,是以到達不了這一條正則
(7) location /images/abc {}
最長字元比對到/images/abc, 優先級最低,繼續往下搜尋其它location, 會發現^~和~存在
(8) location ~ /images/abc {}
比對以/images/abc開頭的,優先級次之,隻有去掉location ^~ /images/ 才會采用這一條
(9) location /images/abc/1.html {}
比對/ images/abc/1.html檔案,如果和正則location ~ / images/ abc/1.html相比,正則優先級更高
優先級總結:
(location =完整路徑) > (location ^~路徑) > (location ~,~*正則順序) > (location 部分起始路徑) > (location /)
location 比對
首先看優先級:精确>字首>正則>一般>通用
優先級相同:正則看上下順序,上面的優先:一般比對看長度,最長比對的優先精确、字首、正則、一般都沒有比對到,最後再看通用比對。
實際網站使用中,至少有三個比對規則定義:
#第一個必選規則
直接比對網站根,通過域名通路網站首頁比較頻繁,使用這個會加速處理,比如說官網。可以是一個靜态首頁,也可以直接轉發給後端應用伺服器
location = / {
root html;
index index.html index.html;
}
#第二個必選規則是處理靜态檔案請求,這是nginx作為http伺服器的強項有兩種配置模式,目錄比對或字尾比對,任選其一或搭配使用
location ^~ /static/ {
root /webroot/static/;
}
location ~* \.(html|gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}
#第三個規則就是通用規則,比如用來轉發帶.php、.jsp字尾的動态請求到後端應用伺服器非靜态檔案請求就預設是動态請求
location / {
proxy_pass http://tomcat_server;
}
rewrite
rewrite功能就是,使用nginx提供的全局變量或自己設定的變量,結合正規表達式和标記位實作URL重寫以及重定向。
比如:更換域名後需要保持舊的域名能跳轉到新的域名上、某網頁發生改變需要跳轉到新的頁面、網站防盜鍊等等需求。
rewrite.隻能放在server{}, location{},if{}中,并且預設隻能對域名後邊的除去傳遞的參數外的字元串起作用,
例如http: L /www.kgc.com/ abc/bbs/index.php?a=1&b=2隻對/abc/bbs/ index . php重寫。
rewrite跳轉實作:
Nginx:通過ngx_ http_ rewrite_ module 子產品支援URL重寫、支援if條件判斷,但不支援else跳轉:從一個location跳轉到另一個location,循環最多可以執行10次,超過後nginx将傳回500錯誤
PCRE支援: perl相容正規表達式的文法規則比對
重寫子產品set指令:建立新的變量并設其值
rewrite執行順序如下:
(1) 執行server 塊裡面的rewrite 指令。
(2) 執行location 比對。
(3) 執行標明的location 中的rewrite 指令。
文法格式: rewrite <regex> <replacement> [flag];
regex:表示正則比對規則。
replacement:表示跳轉後的内容。
flag:表示rewrite支援的flag标記。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsQTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SOwgzN2QTOxkzN2kTM0YTMvwlMxEDMyIDMy8CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
Rewrite跳轉場景:
調整使用者浏覽的URL,看起來更規範,合乎開發及産
品人員的需求。
為了讓搜尋引擎搜錄網站内容及使用者體驗更好,企業會
将動态URL位址僞裝成靜态位址提供服務。
網址換新域名後,讓舊的通路跳轉到新的域名.上。例如通路京東的360buy.com會跳轉到jd.com。
服務端某些業務調整,比如根據特殊變量、目錄、用戶端的資訊進行URL調整等。
###flag标記說明###
last :本條規則比對完成後,繼續向下比對新的location URL規則, 一般用在server和if中。
break :本條規則比對完成即終止,不再比對後面的任何規則,一般使用在location 中。
redirect:傳回302臨時重定向,浏覽器位址會顯示跳轉後的URL位址。
permanent:傳回301永久重定向,浏覽器位址欄會顯示跳轉後的URL位址。
rewrite示例:
(1)基于域名的跳轉
現在公司舊域名www.kgc.com有業務需求變更,需要使用新域名www.benet.com代替,但是舊域名不能廢除,需要跳轉到新域名上,而且後面vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_nameWWw.kgc.com; #域名修改
charset utf-8; #編碼格式
access_ 1og /var/log/nginx/www.kgc.com-access.log; #日志修改
location / { #添加域名重定向
if ($host = 'WWW.kgc.com') { #$host為rewrite全局變量,代表請求主機頭字段或主機名
rewrite ^/(.*)$ http://www.benet.com/$1 permanent; #$1為 正則比對的内容,即“域名/"之後的字元串
}
root html;
index index.html index.htm;
}
}
echo "192.168.80.10 www.kgc.com www.benet.com" >> /etc/hosts
systemctl restart nginx
浏覽器輸入模拟通路http://www.kgc.com/test/1.html (雖然這個請求内容是不存在的)
會跳轉到www.benet.com/test/1.html,檢視元素可以看到傳回301,實作了永久重定向跳轉,而且域名後的參數也正常跳轉。
(2)基于用戶端IP通路跳轉
今天公司業務新版本上線,要求所有IP通路任何内容都顯示, 個固定維護頁面,隻有公司IP : 192.168.80.10通路正常。
vim /usr/local/nginx/conf /nginx.conf
server {
server_nameWWw.kgc.com; #域名修改
charset utf-8; #編碼格式
access_ 1og /var/log/nginx/www.kgc.com-access.log; #日志修改
#設定是否合法的IP标記
set $rewrite true; #設定變量$rewrite,變量值為boole值true
#判斷是否為合法IP
if ($remote_addr = "192.168.80.10"){ #當用戶端IP為192.168.80.10時,将變量值設為false,不進行重寫
set $rewrite false;
}
#除了合法IP,其它都是非法IP,進行重寫跳轉維護頁面
if ($rewrite = true) { #當變量值為true時,進行重寫
rewrite (.+) /weihu.html; #将域名後邊的路徑重寫成/weihu. html,例如www. kgc.com/weihu.html
}
location = /weihu.html {
root /var/ www/html; #網頁傳回/var/www/ html/weihu. html的内容
}
location / {
root html;
index index.html index.htm;
}
}
(3)基于舊域名跳轉到新域名後面加目錄
現在通路的是http://bbs.kgc.com/postL,現在需要将這個域名下面的通路都跳轉到http: L /www.kgc.com/bbs/post
vim /usr/1ocal/nginx/conf/nginx.conf
server {
listen 80;
server_namebbs.kgc.com; #域名修改
charset utf-8;
access_1og /var/1og/nginx/WWW.kgc.com-access.log;
#添加
location /post {
rewrite (.+) http://www.kgc.com/bbs$1 permanent; #這裡的$1為位置變量,代表/post
}
location / {
root html;
index index.html index.htm;
}
}
mkdir -p /usr/local/nginx/html/bbs/post
echo "this is 1.html" >> /usr/1ocal/nginx/html/bbs/post/1 . html
echo "192.168.80.10 bbs.kgc.com"
systemctl restart nginx
使用浏覽器通路http://bbs.kgc.com/post/1.html跳轉到http://www. kgc.com/bbs/post/1.html
(4)基于參數比對的跳轉
現在通路http: //www.kgc.com/ 100- (100|200)-100.html跳轉到http://www.kgc.com頁面。
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name Www.kgc.com; #域名修改
charset utf-8;
access_log /var/log/nginx/www.kgc.com-access.log;
if ($request_uri ~ ^/100-(1001200)-(\d+).html$) {
rewrite (.+) http://www.kgc.com permanent;
}
location / {
root html;
index index . html index . htm;
}
}
儲存後并退出
systemctl restart nginx
使用浏覽器通路http://www.kgc.com/100-200-100.html或http://www.kgc.com/100- 100-100.html跳轉到http://www.kgc.com頁面。
(5)基于目錄下所有php結尾的檔案跳轉
要求通路http:/ /www.kgc.com/upload/123.php跳轉到首頁。
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name www.kgc.com; #域名修改
charset utf-8;
access_1og /var/1og/nginx/www.kgc.com-access.log;
location ~* /up1oad/.*\.php$ {
rewrite (.+) http://www.kgc.com permanent;
}
location / {
root html:
index index.html index.htm;
}
}
systemctl restart nginx
浏覽器通路http://www.kgc.com/upload/123.php跳轉到http://www.kgc.com頁面。
rewrite 基于跳轉的實驗
實驗1
1、基于域名的跳轉
現在公司舊域名www.123.com有業務需求變更,需要使用新域名www.456.com代替,但是舊域名不能廢除,需要跳轉到新域名上,而且後面的參數保持不變。
首先是修改配置檔案
vim /usr/local/nginx/conf/nginx.conf
儲存退出後
我們遞歸建立日志檔案目錄/var/log/nginx
重新開機nginx之後
我們往host檔案中添加本機的ip對應域名
之後檢視/etc/hosts
之後我們登陸本機浏覽器,分别輸入www.123.com、www.456.com
可以發現成功登陸
打開消息後,看到123.com被自動調轉到456.com并且傳回值為301(永久重定向)
實驗2
2、基于用戶端 IP 通路跳轉
今天公司業務新版本上線,要求所有 IP 通路任何内容都顯示一個固定維護頁面,隻有公司固定 IP :192.168.206.5(本機)通路正常進行維護。(公司域名www.123.com)
首先還是老樣子,本機進去修改配置檔案
vim /usr/local/nginx/conf/nginx.conf
如圖所示進行修改
随後遞歸建立日志目錄/var/log/nginx
建立引導維護目錄 /var/www/html
echo建立weihu.html檔案
重新開機伺服器
驗證:本機206.5進去實驗
完全沒問題
下面開一台206.3的客機
echo '192.168.206.5 www.123.com' >> /etc/hosts #host檔案中加入本機的域名和IP
可以發現,客機無論是使用IP還是域名,都被引導去維護界面了
實驗3
3、基于舊域名跳轉到新域名後面加目錄
現在通路的是 http://www.123.com,現在需要将這個域名下面的通路都跳轉到http://www.456.com/456
首先老樣子,
vim /usr/local/nginx/conf/nginx.conf
進去後如圖所示修改
首先是去建立日志目錄
然後是去建立跳轉目錄
然後是去添加host檔案
然後是去/usr/local/nginx/html/456/opt裡穿件一個1.html檔案
完成後重新開機nginx
然後通路www.456.com/opt去檢視下
發現成功跳轉
5、基于目錄下所有 php 結尾的檔案跳轉
要求通路 http://www.123.com/upload/1.php 跳轉到首頁。
首先是老樣子,進去修改配置檔案
vim /usr/local/nginx/conf/nginx.conf
然後建立日志目錄
重新開機nginx服務
最後是添加host檔案