一、什麼是重定向
學過計算機網絡的同學對重定向會有一定的了解,老師在講到HTTP協定的時候會說到幾個狀态碼。其中 2xx代表成功,3xx代表重定向。在重定向中比較重要的就是301——永久重定向,它表示請求的資源已經被配置設定到新的URL,以後應使用資源現在所指的URL。和302——臨時性重定向,它表示請求的資源已經被配置設定到新的URL,希望使用者本次能使用新的URL通路。說了這麼多,什麼是重定向呐?個人通俗的了解:伺服器上面的資源換了個位置(就是搬新家,原來在那個地方的資源放到了别處。當有客戶要通路這個資源時,把新的位置告訴客戶,讓客戶去指定的地方快找)。
說完個人了解來看一下概念:通過各種方法将網絡請求重新定個方向轉到其他位置(分為外部和内部)。外部重定向就是在URL中能看到重新定位到其它位置,内部重定向URL處沒有表現
二、重定向簡單執行個體
在開始說之前先來看一個簡單的例子
項目的目錄結構
在.htaccess檔案中輸入下面代碼
RewriteEngine on
RewriteRule ^(.*)\.htm$ $1.html
因為我配置了虛拟站點是以需要在apache-》conf-》extra下面找到httpd-vhostxs.conf檔案
把AllowOverride none改為all(如果你的已經是ALL就不需要改了)
如果大家對虛拟站點不知道,可以參考一下其他人的部落格了解一下
儲存配置重新啟動apache,就可以通路one.html檔案了
注意:我這裡通路的是one.htm但是最後輸出的是one.html裡面的内容,這裡因為我在.htaccess檔案裡面使用了比對規則,把通路htm的檔案重定向到html檔案上面
三、apache mod_rewrite子產品基礎知識
(一)、RewriteBase
RewriteBase是指定整個URL操作的路徑
文法:RewriteBase URL-path
使用說明:設定了目錄級别的基準URL
實戰
沒有設定rewriteBase和設定了rewriteBase的比較
先看一下目錄結構
①:沒有設定RewriteBase
.htaccess檔案内容
RewriteEngine on
RewriteRule ^(.*)\.htm$ /$1.html
注意/表示你項目配置的根目錄,我配置的根目錄為E:/PHPstorm/one
效果圖
②:設定RewriteBase
RewriteEngine on
RewriteBase /two/
RewriteRule ^(.*)\.htm$ $1.html [R]
效果圖
比較可以發現加了RewriteBase,就會以RewriteBase指定的目錄為根目錄進行通路。如果不加RewriteBase就會按照原來配置的根目錄來通路。
(二)、RewriteRule 文法說明
文法:模式比對 替換的url [flags]
說明
①:模式比對支援perl格式的正規表達式和rewrite的變量
②:多個flag之間用逗号隔開
①:RewriteRule R flag說明
使用說明
強制外部重定向,後面可以加301或302跳轉,預設值為302
例子
RewriteRule ^/?(.*)\.html /src/$1.php [R=302]
這是一個外部重定向
②:RewriteRule C flag說明
使用說明
連接配接下一條規則
例子:
RewriteEngine on
RewriteRule ^/?(.*)\.html /src/$1.htm [C]
RewriteRule ^/?(.*)\.html /src/$1.php
解釋:隻用第一條規則比對了才能比對第二條規則,他們是一個整體,如果第一條規則沒有比對,那麼第二條規則就不會比對
實戰
.htaccess檔案内容
RewriteEngine on
RewriteRule ^(.*)\.htm /$1.html [C]
RewriteRule ^(.*)\.html /$1.php
檔案的目錄結果
接下來通路two.htm
發現重定向到了two.php裡面(内部重定向)
③:RewriteRule L flag說明
使用說明:最後一條比對,立即停止重寫,并不再使用其他重寫規則
例子
RewriteEngine on
RewriteRule ^(.*)\.htm$ /$1.html [L]
RewriteRule ^(.*)\.tx$ /$1.txt
解釋:加上L标簽表示當第一行比對了,下一行就不比對了。如果沒有比對下一行再比對
實戰
.htaccess檔案内容
RewriteEngine on
RewriteRule ^(.*)\.htm$ /$1.html [L]
RewriteRule ^(.*)\.tx$ /$1.txt
目錄結構
接下來通路doc.tx和one.htm來驗證
④:RewriteRule NE flag說明
使用說明:不對URL中的特殊字元進行hexcode轉碼
例子
RewriteRule ^(.*)\.htm$ /index.html#$1 [R,NE]
加上NE表示不對#号進行轉義
實戰
.htaccess檔案内容
RewriteEngine on
RewriteRule ^(.*)\.htm$ /index.html#$1 [R,NE]
效果
如果不加NE,效果如下
把#号轉義成了%23
⑤:RewriteRule NC flag說明
使用說明:不區分大小寫
例子
RewriteEngine on
RewriteRule ^test/(.*)\.htm /two/$1.html [NC]
加上NC,表示對test不區分大小寫,就是你輸入test和TEST是一樣的
實戰
.htaccess檔案内容
RewriteEngine on
RewriteRule ^test/(.*)\.htm /two/$1.html [NC]
效果圖(test小寫)
效果圖(TEST大寫)
如果在.htaccess檔案中把NC去掉
效果圖
⑥:RewriteRule G flag說明
使用說明:請求的網頁已經失效
例子
RewriteEngine on
RewriteRule ^two/.*$ - [F]
把two目錄失效
實戰
.htaccess檔案内容
RewriteEngine on
RewriteRule ^two/.*$ - [F]
我的目錄結構為
當通路two目錄時會出現(403禁止通路)
⑥:RewriteRule QSA flag說明
使用說明:用于在URL截取查詢的字元串
例子
RewriteEngine on
RewriteRule ^two/(.*)$ /two.php?url=$1 [R,QSA]
實戰
.htaccess檔案内容
RewriteEngine on
RewriteRule ^two/(.*)$ /two.php?url=$1 [R,QSA]
效果圖
如果不加QSA,效果圖如下
![在這裡插入圖檔描述](https://img-blog.csdnimg.cn/20191009085248183.png
發現它隻會截取到two.php後面的參數不會截取
(三)、RewriteCond
文法:RewriteCond testString CondPattern(比對模式) [flags]
使用說明:RewriteCond定義了一個規則條件
①:RewriteCond通路rule變量
實戰
.htaccess檔案内容
RewriteEngine on
RewriteCond $1 "two"
RewriteRule ^(.*)\.htm$ /$1.html
說明:隻有滿足你通路的htm檔案名為two時才能完成比對
如果你通路one.htm,就會出現404
如果你通路two.htm,就會成功!
②:RewriteCond 伺服器變量
TestString 使用說明 %{NAME_OF_VARIABLE}
實戰
.htaccess檔案内容
RewriteEngine on
RewriteCond %{HTTP_HOST} "127.0.0.1"
RewriteRule ^(.*)\.htm$ http://localhost/$1.html [R]
伺服器變量還有如下
----------------------------------------------------------------------------------------------照片來源來源慕課網
③:RewriteCond cond變量
TestString 使用說明%1-9
%1-9是RewriteCond條件中最後符合條件中的分組成分
實戰
.htaccess檔案内容
RewriteEngine on
RewriteCond %{HTTP_HOST} "127.0.0.(.*)"
RewriteCond %1 "1"
RewriteRule ^(.*)\.htm$ http://localhost/$1.html [R]
效果圖
如果把.htaccess檔案内容改成下面的代碼
RewriteEngine on
RewriteCond %{HTTP_HOST} "127.0.0.(.*)"
RewriteCond %1 "2"
RewriteRule ^(.*)\.htm$ http://localhost/$1.html [R]
效果圖
是找不到的
③:RewriteCond CondPattern(比對模式)
CondPattern使用說明 -d表示是否目錄 -f表示是否是檔案
flag中or的用法,or是條件判斷的或如果不加預設值為and
例子
#RewriteCond %{REQUEST_FILENAME} !-d 的意思是通路的路徑不是一個目錄時RewriteRule才能生效
RewriteCond %{REQUEST_FILENAME} !-d
#RewriteCond的 %{REQUEST_FILENAME} !-f 的意思是通路的路徑不是一個檔案時RewriteRule才能生效
RewriteCond %{REQUEST_FILENAME} !-f
實戰
.htaccess檔案内容
RewriteEngine on
RewriteCond E:/PHPstorm/one -d [OR]
RewriteCond E:/PHPstorm/onew -d
RewriteRule ^(.*)\.htm$ /$1.html
效果圖:
如果把 OR去掉
RewriteEngine on
RewriteCond E:/PHPstorm/one -d
RewriteCond E:/PHPstorm/onew -d
RewriteRule ^(.*)\.htm$ /$1.html
效果圖:
就會出現404,這是因為沒有OR,預設值為and,RewriteCond的兩個條件都得滿足才能通路,第二個cond條件中不是目錄,不符合,是以出現了404
(四)、RewriteMap
文法 RewriteMap MapName MapType MapSource
MapName: 命名給RewriteRule調用
MapType: Map檔案類型 有txt,rnd等
MapSource:map檔案路徑
如何通路txt格式檔案
${MapName:LookupKey|DefaultValue}
例子
RewriteMap pages txt:E:\XAMPP\XAMPP\apache\conf\map.txt
test1 pagetest1
test2 pagetest2
RewriteRule ^(.*).shtml $(pages:$1|page).php
實戰
虛拟站點配置
向map.txt中輸入一下内容,并重新啟動apache
.htaccess檔案内容
RewriteEngine on
RewriteRule ^(.*)\.shtml$ ${pages:$1|NOTFOUND}.html
在one目錄下面建立兩個html如下圖(為了效果明顯)
效果圖:
rnd檔案也和txt比較類似,可以參考下面的網站
RewriteMap