(轉)Apache Rewrite 詳解

(轉)Apache Rewrite 詳解


Apache Rewrite 詳解一 入門
RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php
就這兩行. 而後就完成了URL重寫功能了. 

首先服務器是須要支持網站使用 .htaccess 文件模式. 這個須要服務器或者虛擬主機的配置段裏給你配置 AllowOverride, 一般設置成 All 容許全部指令在 .htaccess 生效. 再看第一行:
RewriteEngine on 這行告訴apache服務器, 這個目錄要使用URL重寫功能了.
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php 這行是具體的重寫規則, 以上是若是有URL來訪問該目錄裏的文件, 若是URL不是以 .js, .ico, .gif, .jpg, .png, .css 這幾種結尾的話. 那麼所有調用 目錄下的 index.php 文件. 這個提及來比較費勁, 搞個具體的例子. 好比咱們又一個網站, 域名爲: www.test.com 該站支持 .htaccess 功能. 咱們把上面兩行保存爲 .htaccess 放到網站目錄下. 若是WINDOW下不容許保存這樣的文件名的話不要緊. 隨便保存爲 x.htaccess, 而後在DOS下 rename x.htaccess .htaccess 就好了.
在www.test.com 網站根目錄下放3個文件, 一個是 .htaccess, 一個是 logo.png, 一個是 index.php
測試一: 在瀏覽器地址欄裏輸入: http://www.test.com/ 很正常. 頁面應該默認顯示 index.php 文件的內容.
測試二: 在瀏覽器地址欄裏輸入: http://www.test.com/logo.png 也很正常. 網頁裏應該看到了這個png圖片了.
測試三: 在瀏覽器地址欄裏輸入: http://www.test.com/test.php 這樣通常來講, 若是沒開重寫功能的話. 一般你會看到404錯誤. 這說明你服務器APACHE的rewrite功能沒生效. 否則你看到的是和 測試一同樣的內容. 由於請求 test.php 被定向到 index.php. 實際上是和訪問http://www.test.com/index.php 一個效果. 這就是apache最簡單的rewrite功能了.
OK, 另外再說名一下 .htaccess 文件裏的一些小事情. 若是你要給指令添加註釋, 防止複雜的重寫規則時間常了要修改的話還要費勁去看,或者協做開發讓別人能很容易看懂. 這樣只要在每行的第一個字符寫成"#" 就好了. 一般的指令的第一個字符是一個大寫英文字母, 後面的是按照駝峯命名法寫出, 好比開啓重寫指令: RewriteEngine, 指令值通常是小寫的字符串. 像上面的 RewriteEngine on
再看一下完整的簡單的.htaccess文件代碼:
#該目錄下使用Apache Rewrite 功能. RewriteEngine on   #全部的訪問請求, 除了是以 .js, .ico, .gif, .jpg, .png, .css 結尾, 都定向到index.php腳本 RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php 上面的重寫規則指令用到了正則表達式. 這方面不太瞭解的話想去補充一下. 否則後面的部分會看起來比較費勁.
關於 RewriteRule 這個是比較能讓人花點時間玩的東西了. 下篇問詳細介紹它的用法和參數.
-----------------------------------------------------------------------------------------------------------------
Apache Rewrite 詳解二 參數標誌[Flag]
上一篇聊了一下最簡單的重寫模式. 在進入比較好玩的重寫模式以前. 先給說名一下重寫規則後面的那些中括號裏的大寫字符是什麼意思. 否則會讓你看後面的代碼暈頭轉向的. 關於這些參數的說明在 apache.org 的官方文檔裏有說明, 惋惜沒有中文的. 我大概的翻譯了一下表面意思. 建議去看原E文文檔. E文實在很差的先湊合着看看. 官方關於 Rewrite Flag 文檔地址在: http://httpd.apache.org/docs/2.2/rewrite/rewrite_flags.html
 
重寫規則的通常模式爲下面的語法.
RewriteRule pattern target [Flag1,Flag2,Flag3]
RewriteRule 規則能夠在後面添加標誌(Flag), 能夠又多個 flag, 多個 flag 用逗號"," 鏈接.
 
先說明一下一個比較特別的 target 值: "-", 若是目標是 "-" 的話, 那麼被請求的URL不會被修改掉.
 
下面詳細簡介一下各個 flag 表明的意思.
 
C|chain
字符 'C' 或者 字符串 'chain' 表示出了該行重寫規則外還要有其餘的重寫規則, 至關於一般程序語言的 與符號 '&' , 若是第一條規則條匹配的話進行下一項條件匹配. 若是第一條或者中間一條匹配不成功. 在其後的都會被跳過.
 
CO|cookie
字符 'CO' 或者 字符串 'cookie' 表示當某些特殊的規則被匹配到的時候, 容許設置一個COOKIE, 設置參數包含3個必須字段和2個可選字段.
三個必須的字段是設定COOKIE的名字, 值, 還有這個COOKIE的所屬域名, 另外兩個可選的字段是COOKIE的生存時間和路徑.默認的COOKIE生存時間是瀏覽器的會話時間. 默認的路徑是 '/', 針對整個網站.
實際的使用例子想下面這樣
RewriteEngine On
# RewriteRule 匹配模式 - [CO=COOKIE名稱:COOKIE值:COOKIE域名:生存時間:路徑] 各個參數用冒號:鏈接
RewriteRule ^/index.html - [CO=mycookie:myCookieValue:.test.com:1440:/]
#RewriteRule ^/index.html - [CO=mycookie:myCookieValue:.test.com] 或者省略後面的參數.
上面的規則的意思是在請求 index.html 文件的時候設置一個COOKIE值. COOKIE名是 mycookie, 值是:myCookieValue, 生效的域名是 .test.com, 生效時間是分鐘計算的. 也就是生存時間是1天=24小時=1440分鐘.
 
E|env
字符 'E' 或者 字符串 'env' 表示你能夠設置一個環境變量. 注意一下變量在這個規則運行後生效.
看一個簡單的例子, 就是apache在記錄日誌的時候不記錄圖片的讀取記錄. 那麼下面的規則就有用了.
RewriteRule \.(png|gif|jpg) - [E=image:1]
CustomLog logs/access_log combined env=!image
 
F|forbidden
字符 'F' 或者 字符串 'forbidden' 表示禁止訪問. Apache服務器會返回403禁止訪問狀態碼給客戶端.
下面的規則表示獲取或者下載 exe程序文件是被顯示禁止訪問.
RewriteRule \.exe - [F]
 
G|gone
字符 'G' 或者 字符串 'gone' 表示服務器響應狀態碼爲:410 一般使用該標誌的時候 target 目標值設置成 "-" 被請求的資源是有效的.
下面的例子表示舊的資源是有效的. 而且不在意大小寫.
RewriteRule oldproduct - [G,NC]
 
H|handler
字符 'H' 或者 字符串 'handler' 表示強制使用某類型處理程序處理被請求的資源. 好比請求一些不帶後綴的文件的時候. 下面的列子表示當請求的URL裏沒有帶'.'的時候, 強制使用PHP來處理這類的請求.
RewriteRule !\. - [H=application/x-httpd-php]
 
L|last
字符 'L' 或者 字符串 'last' 表示當前規則是最後一條規則,中止分析之後規則的重寫。該標誌的使用頻率很是高.
RewriteCond %{REQUEST_URI} !index\.php
RewriteRule ^(.*) index.php?req=$1 [L]
必定要注意的地方, 使用[L]標誌的時候, 必定要注意你的匹配條件, 不會很是容易讓你的重寫規則陷入死循環, 好比你要定義頁面全部頁面請求都重寫到一個 index.php 文件, 那麼必定要注意在匹配條件時肯定當請求的腳本不是index.php時才執行重寫規則. 否則很明顯當前頁面請求的是 index.php, 固然 這個請求被重寫到 index.php 而後index.php又被重寫到index.php.. 這樣反覆執行. 頁面會報錯. 錯誤日誌會記錄報告你超出最大的重定向次數.
 
N|next
字符 'N' 或者 字符串 'next' 表示從新回到規則頂部重複執行. 通常在極端狀況下用這個標誌. 至關於一個while循環, 知道匹配失敗時返回. 下面的例子表示把請求地址中的全部A字符替換成B字符.
RewriteRule (.*)A(.*) $1B$2 [N]
 
NC|nocase
字符 'NC' 或者 字符串 'nocase' 表示請求的規則部分不區分大小寫. 相似正則式裏的/xxx/i 模式.
RewriteRule (.*\.(jpg|gif|png))$ http://images.test.com$1 [P,NC]
 
NE|noescape
字符 'NE' 或者 字符串 'noescape' 表示不對URL中的特殊字符進行 hexcode 轉碼.看下面的例子:
RewriteRule ^/share/(.+) /goShare.html#$1 [NE,R]
上面的例子表示全部請求 /share/xxx.xx的請求都會被定向到/goShare.html文件上. 而且後面的部分做爲一個#後面的值. 若是不加NE標誌的話, #將被轉義成 # 這樣就形成 404 錯誤了.
 
NS|nosubreq
字符 'NS' 或者 字符串 'nosubreq' 表示只用於不是內部子請求.好比,在mod_include試圖搜索可能的目錄默認文件(index.xxx)時, Apache會內部地產生子請求。對子請求,它不必定有用的,並且若是整個規則集都起做用,它甚至可能會引起錯誤。因此,能夠用這個標記來排除某些規則。根據你的須要遵循如下原則: 若是你使用了有CGI腳本的URL前綴,以強制它們由CGI腳本處理,而對子請求處理的出錯率(或者開銷)很高,在這種狀況下,可使用這個標記。
 
P|proxy
字符 'P' 或者 字符串 'proxy' 標誌須要模塊 mod_proxy 支持, 相似一個分發器網關的做用.好比網站的全部圖片想用單獨的一臺服務器來運行. 那麼先前的代碼裏的圖片請求的時候, 直接定向到圖片服務器去.
RewriteRule (.*)\.(jpg|gif|png) http://images.example.com$1.$2 [P]
使用[P]標誌, 意味着使用了[L]標誌, 由於使用該標誌後立刻就重定向到新地址了. 後面的重寫規則會被忽略掉.
 
PT|passthrough
字符 'PT' 或者 字符串 'passthrough' 表示替換URL請問部分的地址.看例子
Alias /icons /usr/local/apache/icons
RewriteRule /pics/(.+)\.jpg /icons/$1.gif [PT]
當請求/pics/下的圖片文件時, 實際是返回的是 /icons/目錄下的同名文件. 須要注意的是必定要設置 [PT] 標誌. 不然Alias設置無效.
 
QSA|qsappend
字符 'QSA' 或者 字符串 'qsappend' 不怎麼好表示. 看例子:
RewriteRule /pages/(.+) /page.php?page=$1 [QSA]
若是又標誌: [QSA] 那麼重寫後的URL是: /page.php?page=123&one=two
若是沒有[QSA]標誌, 那麼結果是: /page.php?page=123
此標記強制重寫引擎在已有的替換串中追加一個請求串,而不是簡單的替換。 若是須要經過重寫規則在請求串中增長信息,就可使用這個標記。
 
R|redirect
字符 'R' 或者 字符串 'redirect' 表示進行重定向, 狀態碼在300-399裏隨機出, 默認是 302 重定向.一般和標誌L一塊兒使用. 使用模式: [R[=302]]
 
S|skip
字符 'S' 或者 字符串 'skip' 表示跳過執行下面的幾個重寫規則. 又點相似goto. 看下面的例子, 若是URL請求的文件不存在的話就跳過下面的兩行重寫規則.
# 請求的文件是否存在
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# 不存在的狀況
RewriteRule .? - [S=2]
RewriteRule (.*\.gif) images.php?$1
RewriteRule (.*\.html) docs.php?$1
 
T|type
字符 'T' 或者 字符串 'type' 表示爲apache設置特定請求的響應類型. 也就是常說的 MIME type,好比一個perl腳本. 但願給客戶端顯示文本源碼, 那麼能夠這樣作:
RewriteRule \.pl$ - [T=text/plain]
或者你的服務器上的文件沒有設置擴展名. 那麼能夠通知重寫添加該文件的類型. 方便客戶端顯示.
RewriteRule IMG - [T=image/jpg]
 
以上就是Apache 官方文檔提到的所有標誌值及其相關的意思了. 接下來咱們將介紹他們用到具體的實際例子中去. 上面代碼的例子看不懂不要緊. 接下來我會很詳細的解釋它的. :)   這篇就先到這裏吧.
------------------------------------------------------------------------------------------------------------------ Apache Rewrite 詳解三 服務器變量
上一篇日誌大概瞭解了重寫規則的標誌量的意思, 這篇先把Apache 能提供給rewrite模塊的服務器變量信息瞭解一下. 否則會在之後的重寫規則中對變量的大概內容都不瞭解. 理解起來就比較費勁了.
須要注意的一點是在 .htaccess 文件中使用服務器參數是的寫法是: %{參數名}, 好比HOST名稱: %{HTTP_HOST}
Apache提供給rewirte模塊的環境變量大概分紅5個類型. 下面一一說明.
 
第一部分: HTTP headers 部分參數
參數名稱: HTTP_USER_AGENT
樣例參考值: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8
說明: 至關於PHP中的服務器參數: $_SERVER["HTTP_USER_AGENT"]
參數名稱: HTTP_REFERER
樣例參考值: http://www.test.cn/test.php
說明: 至關於PHP中的服務器參數: _SERVER["HTTP_REFERER"]
參數名稱: HTTP_COOKIE
樣例參考值: ZDEDebuggerPresent=php,phtml,php3
說明: 至關於PHP中的服務器參數: $_SERVER["HTTP_COOKIE"]
參數名稱: HTTP_FORWARDED
樣例參考值: 若是使用代理服務器的話會是代理服務器的IP地址, 本地不容易搭環境測試出值來.
說明: 至關於PHP中的服務器參數: $_SERVER["HTTP_FORWARDED"]
參數名稱: HTTP_HOST
樣例參考值: www.test.com
說明: 至關於PHP中的服務器參數: $_SERVER["HTTP_HOST"]
參數名稱: HTTP_PROXY_CONNECTION
樣例參考值: 網絡鏈接代理方面的信息. 和HTTP_FORWARDED參數同樣. 本地不容易搭環境測試出值來.
說明: PHP中貌似未提供這樣的服務器信息值. 若是又的話可能等值於: $_SERVER["HTTP_PROXY_CONNECTION"]
參數名稱: HTTP_ACCEPT
樣例參考值: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
說明: 至關於PHP中的服務器參數: $_SERVER["HTTP_ACCEPT"]
 
第二部分: server internals 部分參數
參數名稱: DOCUMENT_ROOT
樣例參考值: C:/webRoot/t
說明: 至關於PHP中的服務器參數: $_SERVER["DOCUMENT_ROOT"]
參數名稱: SERVER_ADMIN
樣例參考值: youemailaddress@gmail.com
說明: 至關於PHP中的服務器參數: $_SERVER["SERVER_ADMIN"]
參數名稱: SERVER_NAME
樣例參考值: www.test.com
說明: 至關於PHP中的服務器參數: $_SERVER["SERVER_NAME"]
參數名稱: SERVER_ADDR
樣例參考值: 127.0.0.1
說明: 至關於PHP中的服務器參數: $_SERVER["SERVER_ADDR"]
參數名稱: SERVER_PORT
樣例參考值: 80
說明: 至關於PHP中的服務器參數: $_SERVER["SERVER_PORT"]
參數名稱: SERVER_PROTOCOL
樣例參考值: HTTP/1.1
說明: 至關於PHP中的服務器參數: $_SERVER["SERVER_PROTOCOL"]
參數名稱: SERVER_SOFTWARE
樣例參考值: Apache/2.2.11 (Win32) PHP/5.2.9-1
說明: 至關於PHP中的服務器參數: $_SERVER["SERVER_SOFTWARE"]
 
第三部分: connection & request 部分參數
參數名稱: REMOTE_ADDR
樣例參考值: 127.0.0.1 正在瀏覽當前頁面用戶的 IP 地址。
說明: 至關於PHP中的服務器參數: $_SERVER["REMOTE_ADDR"]
參數名稱: REMOTE_HOST
樣例參考值: 127.0.0.1 正在瀏覽當前頁面用戶的主機名。反向域名解析基於該用戶的 REMOTE_ADDR
說明: 至關於PHP中的服務器參數: $_SERVER["REMOTE_HOST"]
參數名稱: REMOTE_PORT
樣例參考值: 2574 (變化的值)用戶鏈接到服務器時所使用的端口
說明: 至關於PHP中的服務器參數: $_SERVER["REMOTE_PORT"]
參數名稱: REMOTE_USER
樣例參考值: 空
說明: PHP 好像未提供相關的$_SERVER值.
參數名稱: REMOTE_IDENT
樣例參考值: 空
說明: PHP 好像未提供相關的$_SERVER值.
參數名稱: REQUEST_METHOD
樣例參考值: GET
說明: 至關於PHP中的服務器參數: $_SERVER["REQUEST_METHOD"]
參數名稱: SCRIPT_FILENAME
樣例參考值: C:/webRoot/t/share77.html
說明: 至關於PHP中的服務器參數: $_SERVER["SCRIPT_FILENAME"]
參數名稱: PATH_INFO
樣例參考值: 空
說明: 至關於PHP中的服務器參數: $_REQUEST["PATH_INFO"]
參數名稱: QUERY_STRING
樣例參考值: a=b&c=d&e=f
說明: 至關於PHP中的服務器參數: $_SERVER["QUERY_STRING"]
參數名稱: AUTH_TYPE
樣例參考值: 空 當 PHP 運行在 Apache 模塊方式下,而且正在使用 HTTP 認證功能,這個是認證的類型
說明: 至關於PHP中的服務器參數: $_SERVER["AUTH_TYPE"]
 
第四部分: date and time 部分參數
參數名稱: TIME_YEAR
樣例參考值: 2009
說明: 服務器獲取當前的年份值
參數名稱: TIME_MON
樣例參考值: 04
說明: 服務器獲取當前的月份值
參數名稱: TIME_DAY
樣例參考值: 22
說明: 服務器獲取當前的日值
參數名稱: TIME_HOUR
樣例參考值: 16
說明: 服務器獲取當前時間的小時
參數名稱: TIME_MIN
樣例參考值: 26
說明: 服務器獲取當前時間的分鐘
參數名稱: TIME_SEC
樣例參考值: 34
說明: 服務器獲取當前時間的秒
參數名稱: TIME_WDAY
樣例參考值: 3
說明: 服務器獲取當天是星期幾, 從星期日-星期六, 數字從 0-6
參數名稱: TIME
樣例參考值: 20090422162634
說明: 服務器獲取當前的時間, 格式爲: 年月日時分秒
 
第四部分: specials 部分參數
參數名稱: API_VERSION
樣例參考值: 20051115:21
說明: apache 的 API 版本信息.
參數名稱: THE_REQUEST
樣例參考值: GET /share77.html HTTP/1.1
說明: 瀏覽器發給服務器的請求值. 不包括其餘的頭信息.
參數名稱: REQUEST_URI
樣例參考值: /share77.html
說明: 瀏覽器請求的資源信息.
參數名稱: REQUEST_FILENAME
樣例參考值: C:/webRoot/t/share77.html
說明: 被請求的資源的在磁盤的物理地址.
參數名稱: IS_SUBREQ
樣例參考值: false
說明: 若是是 sub-request 則顯示爲 true, 不然爲 false.
參數名稱: HTTPS
樣例參考值: off
說明: 若是鏈接使用 SSL/TLS 模式, 則值爲on , 不然值爲off, 這個參數比較安全, 即便未載入 mod_ssl 模塊時.
OK, 以上就是Apache手冊裏提到的所有的服務器變量信息了. 這篇先到這裏了. 

Apache Rewrite 詳解四 雜項 
前篇介紹了Apache Rewrite 的服務器變量信息. 在進入重寫實戰以前. 有些小細節瞭解一下是很又必要的.
首先一點. 若是在重寫規則的正則裏要使用特殊字符的時候須要在該特殊字符前帶一個轉義字符: 反斜槓, 好比匹配一個百分號:%, 那麼正確的寫法就該是: \%, 其餘的特殊字符均按此寫法.
正反斜模槓
(轉)Apache <wbr>Rewrite <wbr>詳解
(轉)Apache <wbr>Rewrite <wbr>詳解


另外還有官方手冊裏提到的四個比較重要的服務器變量. SCRIPT_NAME, SCRIPT_FILENAME, SCRIPT_URL, SCRIPT_URI
其中 SCRIPT_NAME 和 SCRIPT_FILENAME 是apache會跟蹤的兩個標準CGI/SSI變量, 他們包含的是物理系統視圖.
官方文檔的示例值:
SCRIPT_NAME=/sw/lib/w3s/tree/global/u/rse/.www/index.html
SCRIPT_FILENAME=/u/rse/.www/index.html
另外還會跟蹤兩個非標準的變量 SCRIPT_URL 和 SCRIPT_URI. 他們包含的是邏輯網絡視圖.
官方文檔的示例值:
SCRIPT_URL=/u/rse/
SCRIPT_URI=http://en1.engelschall.com/u/rse/
實際上按照上面的說法看起來
SCRIPT_NAME 的值是資源請求文件在服務器的實際地址.
SCRIPT_FILENAME 資源相對於站點根目錄的實際地址.
SCRIPT_URL 則是URL的相對路徑.
SCRIPT_URI 則是網絡請求的絕度路徑.
不過在實際測試中並未發現是上面的狀況. 服務器配置環境爲WINXP+APACHE2.2.11+PHP-5.2.9, module模式. 和 Linux+Apache2.2.6+PHP-5.2.5, module 模式. 四個變量中 SCRIPT_FILENAME 在沒有 Alians 指令下未腳本在服務器端的實際地址. SCRIPT_NAME爲請求的腳本相對應網站根目錄的地址, 例如:/test.php 另外兩個非標準變量爲空. 若是在 重寫規則中使用上面的四個變量須要注意一下.
另外正則部分又個"!"表示否的意思, 其餘的正則和perl的正則相似. 這方面沒信息的先看看正則方面的資料. 本系列完結後分享一個重寫很系統的圖表. 到時候做爲一個查詢工具. 很是方便.

Apache Rewrite 詳解五 RewriteBase
如今咱們瞭解一下 Apache Rewrite 的重寫規則的具體指令吧.
重寫規則具體有 RewriteBase, RewriteCond, RewriteEngine, RewriteLock, RewriteLog, RewriteLogLevel, RewriteMap, RewriteOptions, RewriteRule 九個指令. 一般最經常使用的是 RewriteEngine, RewriteBase, RewriteCond, RewriteRule 四個指令. 這個咱們要重點講解的. 若是這四個指令運用的比較熟練的話, 不是特別的網站. 基本上你想出什麼樣的URL 均可以知足你的須要了. 其餘的指令就不在講解了. 若是對前面說的4個指令比較熟悉的話. 剩下的去看看 apache 的手冊. 相信掌握這些不會費你不少腦筋.
RewriteEngine 這個指令就不用說了. 就是是否使用 Rewrite 模式的開關, 使用就設置成 on, 不然設置成 off 做用域在: server config, virtual host, directory, .htaccess
咱們這篇日誌專門講解: RewriteBase
RewriteBase 的做用域爲: directory, .htaccess
一般默認的虛擬主機的網站在使用.htaccess 進行重寫規則時不須要執行設置該指令. 由於 RewriteBase 默認值是該 .htaccess 文件所在的目錄地址.
可是若是使用目錄別名的話就須要設置這個指令了. 先看官方手冊的例子. 假設一個網站目錄使用了別名操做: Alias /xyz /abc/def 那麼當客戶端訪問/xyz/xxx.html 文件時是至關於訪問 /abc/def/xxx.html的. 而後看看在使用了別名的狀況下重寫效果. 固然這個 .htaccess 文件在 /abc/def/.htaccess 位置. 內容以下:
RewriteEngine On
RewriteBase /xyz
RewriteRule ^oldstuff\.html$ newstuff.html
假設訪問服務器的: /xyz/oldstuff.html (好比: http://www.test.com/xyz/oldstuff.html 這樣).
服務器處理流程大概是下面的樣子.
第一步, 把alias別名還原成真實的路徑:
/xyz/oldstuff.html -> /abc/def/oldstuff.html   (per-server Alias)
第二步, rewrite前會去掉前綴(也就是.htaccess文件所在的目錄部分這裏是/abc/def/), 而後執行重寫規則, 處理完以後再把前綴添加上去:
/abc/def/oldstuff.html -> /abc/def/newstuff.html   (per-dir     RewriteRule)
第三步, 因爲設定了RewriteBase值,因此路徑最後仍是被還原回去:
/abc/def/newstuff.html -> /xyz/newstuff.html       (per-dir     RewriteBase)
第四步, 重寫規則完成, 別名再次使用. 最後獲得的結果:
/xyz/newstuff.html     -> /abc/def/newstuff.html   (per-server Alias)
實際上至關於請求: /abc/def/newstuff.html, 關於 alias 的用法和意思, 請另行參考 apache 手冊.
這裏要注意的是即便RewriteBase /xyz 這行被註釋掉. 服務器仍是會執行上面的 第一步, 第二步, 後面的不會被執行, 服務器執行完第二步之後就發出一個內部重定向. 按照上面的例子也就是 GET /abc/def/newstuff.html, 因爲GET 模式獲取到第一個是/開頭的, 至關於請求DocumentRoot目錄下的/abc/def/newstuff.html, 換成客戶端請求的模式也就是 http://www.test.com/xyz/oldstuff.html 變成了 http://www.test.com/abc/def/newstuff.html 若是 /xyz 只是目錄的別名, DocumentRoot 目錄下根本沒有實際的物理目錄 abc/def 這樣最終會致使一個 404 報錯.
另外有一點就是在進行重寫規則的時候. apache 會去掉目錄前綴. 注意這個時候剩下的文件名或者相對目錄第一個字符不是 / 開頭的. 而直接是文件名或者目錄這樣的模式. 關於訪問 http://www.test.com 和 訪問 http://www.test.com/ 又什麼不一樣(最後加斜槓和不加斜槓). 服務器已經強制進行過了一次重定向(外部定向)了. 若是服務器未處理這類的事情的話. 就須要手動處理. 否則錯誤日誌漫天飛. 那會是很痛苦的事情呢!
OK, 說完了. 收工先! 下篇說一下 RewriteCond.
Apache Rewrite 詳解六 RewriteCond
RewriteCond 重寫規則執行條件
語法: RewriteCond TestString CondPattern
生效域: server config, virtual host, directory, .htaccess
特別的上面的 TestString, 可提供反向引用. 引用模式爲: %N 其中N爲(0 <= N <=9), 引用當前若干RewriteCond條件中最後符合的條件中的分組成分, 也就是括號裏的內容.不過用到的很少. 反向應用多在RewriteRule裏經常使用.
RewriteCond 語法中的 TestStrng 爲要被檢查的內容, CondPattern 是進行匹配的規則, 它是一個兼容Perl風格的正則表達式和一些其餘的特有字符屬性. 這裏介紹一下.
第一個: ! (感嘆號) 表示否的意思. 好比一個條件: 判斷訪問此頁面的上一頁URL是否包含 sex 字符的話能夠用這樣: RewriteCond %{HTTP_REFERER} !(sex)
第二個: < 就是小於的意思, TestString < CondPattern.
第三個: > 就是大於於的意思, TestString < CondPattern.
第四個: = 相等的意思. <, >, = 三個和一般程序語言使用的 <, >, = 功能相似.
第五個: -d 是不是一個目錄. 判斷TestString是否不是一個目錄能夠這樣: !-d
第六個: -f 是不是一個文件. 判斷TestString是否不是一個文件能夠這樣: !-f
第七個: -s 是不是一個正常的有大小的文件. 判斷TestString是否不是一個正常的有大小的文件能夠這樣: !-s
第八個: -l 是不是一個快捷方式文件. 判斷TestString是否不是一個快捷方式文件能夠這樣: !-l
第九個: -x 是不是一個文件而且又執行權限. 判斷TestString是否不是一個文件而且又執行權限能夠這樣: !-x
第十個: -F 檢查TestString是不是一個合法的文件,並且經過服務器範圍內的當前設置的訪問控制進行訪問。這個檢查是經過一個內部subrequest完成的, 所以須要當心使用這個功能以下降服務器的性能。
第十一個: -U 檢查TestString是不是一個合法的URL,並且經過服務器範圍內的當前設置的訪問控制進行訪問。這個檢查是經過一個內部subrequest完成的, 所以須要當心使用這個功能以下降服務器的性能.
另外: RewriteCond 指令後面可帶 Flag, 如今只要2個可用, 一個是 NC|nocase, 不區分大小寫的意思. 一個是 OR|ornext 表示鏈接下一個條件的意思.
RewriteCond 實際須要使用狀況好比要判斷一個條件成真的時候才執行相關的重寫操做. 緊接着它下面的 RewriteRule 老是在RewriteCond 條件判斷爲真的時候才被執行.
看下面的一個例子:
#開啓服務器重寫模式
RewriteEngine on
#來自 www.test.cn 的鏈接訪問本站時都只能訪問 test.php 這頁.
RewriteCond %{HTTP_REFERER} (www.test.cn)
RewriteRule (.*)$ test.php
#來自 www.test.com 的鏈接訪問本站時都只能訪問 newTest.php 這頁.
RewriteCond %{HTTP_REFERER} (www.test.com)
RewriteRule (.*)$ newTest.php
OK, RewriteCond 就介紹到這裏了. 其實很簡單. 就想程序裏的 if() 這樣的效果. 下篇聊一下   RewriteRule
Apache Rewrite 詳解六 RewriteRul
這兩天回家了一趟. 又匆忙的趕回公司上班. 坐車那個累啊. 繼續把 Apache 重寫規則部分講完.
前面的幾篇關於重寫的日誌若是都看了的話. 這裏就很容易了. 值得注意的地方是網站使用URL重寫的話須要服務器配置 RewriteEngine On 和 Options FollowSymLinks, 否則重寫規則不生效.
重寫規則語法很簡單: RewriteRule Pattern Substitution [Flag] 做用域爲: server config, virtual host, directory, .htaccess
指令說明: 匹配部分(Pattern) 是正則匹配URL的正則表達式(注意特殊字符須要轉義處理), 能夠在替換部分(Substitution)使用反向引用匹配部分的內容. 引用模式爲: $N (N爲1-9的整數).
在URL重寫的匹配部分中, 服務器會把請求的URL的一部分刪除掉再傳遞給Pattern部分進行匹配. 重寫結束後再添加上去. 全部日常咱們看到的匹配規則老是不帶網址前面的那些域名的什麼東西的. 也不帶什麼目錄什麼的. 這些 apache已經給刪掉了. 處理完後再加到前面. 可是有個例外就是若是 Substitution 部分是帶 http:// 開頭的話, 那就直接重定向了. 服務器不會把先前刪除的再給加上了. 否則就出錯了.
給出個形象的流程圖. 見下圖:

官方的例子: 重寫規則寫在 httpd.conf 文件裏. 請求地址爲: http://www.test.com/somepath/pathinfo, 看下面幾種結果.
Given Rule => Resulting Substitution
-------------------------------------------------------------------------------
^/somepath(.*) otherpath$1 => 不支持, 無效的重寫語句
^/somepath(.*) otherpath$1 [R] => 不支持, 無效的重寫語句
^/somepath(.*) otherpath$1 [P] => 不支持, 無效的重寫語句
-------------------------------------------------------------------------------
^/somepath(.*) /otherpath$1 => /otherpath/pathinfo
^/somepath(.*) /otherpath$1 [R] =>   http://www.test.com/otherpath/pathinfo   外部重定向
^/somepath(.*) /otherpath$1 [P] =>   不支持, 很傻.
-------------------------------------------------------------------------------
^/somepath(.*) http://www.test.com/otherpath$1 => /otherpath/pathinfo
^/somepath(.*) http://www.test.com/otherpath$1 [R] => http://www.test.com/otherpath/pathinfo   外部重定向
^/somepath(.*) http://www.test.com/otherpath$1 [P] => 不支持, 很傻.
----------------------------------------------   ----------------------------------
^/somepath(.*) http://www.xxx.com/otherpath$1 => http://www.xxx.com/otherpath/pathinfo   外部重定向
^/somepath(.*) http://www.xxx.com/otherpath$1 [R] => http://www.xxx.com/otherpath/pathinfo   外部重定向 [R] 多餘.
^/somepath(.*) http://www.xxx.com/otherpath$1 [P] => http://www.xxx.com/otherpath/pathinfo 內部網關重定向
一樣的請求上面的地址, 若是在 .htaccess 文件裏的寫法. 注意和 httpd.conf 寫法的區別.
好比 .htaccess 文件在目錄一個虛擬主機的根目錄下. 而後請求 http://www.test.com/localpath/pathinfo 看下面的幾種結果.
Given Rule => Resulting Substitution
-------------------------------------------------------------------------------
^localpath(.*) otherpath$1=> /otherpath/pathinfo
^localpath(.*) otherpath$1   [R] =>   http://www.test.com/otherpath/pathinfo 外部重定向
^localpath(.*) otherpath$1   [P] => 不支持, 很傻.
-------------------------------------------------------------------------------
^localpath(.*) /otherpath$1 => /otherpath/pathinfo 注意 /otherpath$1 和 otherpath$1 的區別
^localpath(.*) /otherpath$1 [R] => http://www.test.com/otherpath/pathinfo 外部重定向
^localpath(.*) /otherpath$1 [P] => 不支持, 很傻.
-------------------------------------------------------------------------------
^localpath(.*) http://www.test.com/otherpath$1       /otherpath/pathinfo
^localpath(.*) http://www.test.com/otherpath$1 [R]   http://www.test.com/otherpath/pathinfo 外部重定向
^localpath(.*) http://thishost/otherpath$1 [P] => 不支持, 很傻.
-------------------------------------------------------------------------------
^localpath(.*) http://www.test.com/otherpath$1 => http://www.test.com/otherpath/pathinfo 外部重定向
^localpath(.*) http://www.xxx.com/otherpath$1 [R] => http://www.xxx.com/otherpath/pathinfo 外部重定向 [R] 可省略
^localpath(.*) http://www.xxx.com/otherpath$1 [P] => http://www.xxx.com/otherpath/pathinfo 內部網關重定向
細細的看上面的例子. 重寫規則仍是比較簡單的. 下面放出一些經常使用的例子. 咱們使用 .htaccess 來定義重寫規則. 假設域名爲: www.test.com
.htaccess 放在網站根目錄下. 好比: /.htaccess
例子1: 全部請求都定向到 index.php 腳本, 注意要排除 index.php 自己. 好比就進入死循環了.
RewriteRule !^index\.php$ index.php [L]
例子2: 當請求不存在的資源時, 統必定義到根目錄下的 404.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /404.html [L]
例子3: 限制訪問. 好比來自一些不友好的網站鏈接過來的請求. 不容許訪問. 下例中若是 HTTP_REFERER 中包含 sex 字符, 則不容許訪問.
RewriteCond %{HTTP_REFERER} sex
RewriteRule ^.*$ - [F]
例子4: 按照時間顯示不一樣的頁面, 好比訪問 hello.html 頁面時. 若是 在 8:00-19:00 的時候訪問. 顯示 hello.day.html 其餘時間訪問顯示: hello.night.html
RewriteCond %{TIME_HOUR}%{TIME_MIN} >0700
RewriteCond %{TIME_HOUR}%{TIME_MIN} <1900
RewriteRule ^hello\.html$ hello.day.html
RewriteRule ^hello\.html$ hello.night.html
例子5: 僞靜態化, 好比訪問 /user20.html 則調用viewUser.php 顯示用戶ID爲20的用戶資料
RewriteRule ^user([0-9]*)\.html$ viewUser.php?userid=$1
例子6: 喜歡用二級域名的比較實用了. 好比網站目錄下有 user, upload 等幾個目錄, 能夠經過 http://www.test.com/user 這樣的模式訪問. 可是若是想作成統一用二級域名模式訪問: http://user.test.com , 可是不容許 http://www.test.com/user 這樣訪問. 那麼就像下面這樣來限制.
RewriteCond %{REQUEST_URI} ^/user
RewriteRule ^.*$ http://user.test.net" [L]
關於重寫條件的設置, 能夠任意由你本身來定義. 其餘的例子就很少舉了. URL能夠由你任意擺佈.
重寫還又不少高級功能, 這個須要本身慢慢的研究了. 特別關於負載均衡, 反向代理等其餘不少有意思的高級功能能夠慢慢去玩了. 本篇就到此爲止了.
相關文章
相關標籤/搜索