Apache Rewrite詳細配置與使用說明

1、Rewrite簡介

        Rewirte主要的功能就是實現URL的跳轉,隱藏URL真實地址,可以幫組我們實現擬靜態,擬目錄,域名跳轉,防止盜鏈,搜索引擎得收錄等。Rewirte配置可以通過服務器級的(httpd.conf)和目錄級的 (.htaccess)兩種方式實現。

2、APache配置Rewrite(windows下)

服務器級:
[1]打開Apache的配置文件httpd.conf,將#LoadModule rewrite_module modules/mod_rewrite前面的#去掉;
[2]在httpd.conf中添加如下代碼
<IfModule mod_rewrite.c> 
RewriteEngine On 
#這裏編寫rewrite規則,具體語法,下面會詳細描述
</IfModule> 
[3]重啓Apache即可。
目錄級(.htaccess):
[1]打開Apache的配置文件httpd.conf,將#LoadModule rewrite_module modules/mod_rewrite前面的#去掉;
[2]讓Apache支持.htaccess,需要將httpd.conf中的
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
修改爲:
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
[3]創建.htaccess,創建方法爲用記事本打開點擊文件–另存爲,在文件名窗口輸入“.htaccess”,一定要加上“.”。
[3]將創建的.htaccess拷貝到網站程序的根目錄下即可。
[4].htaccess中的內容如下:
<IfModule mod_rewrite.c> 
RewriteEngine On 
#這裏編寫rewrite規則,具體語法,下面會詳細描述
</IfModule> 

3、服務器變量

[1]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
樣例參考值: [email protected]
說明: 相當於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 模塊時.

4、重寫規則的指令

        對於Rewrite來說共有九個指令:RewriteBase, RewriteCond, RewriteEngine, RewriteLock, RewriteLog, RewriteLogLevel, RewriteMap, RewriteOptions, RewriteRule。通常最常用的是 RewriteEngine, RewriteBase, RewriteCond, RewriteRule 四個指令,下面簡單介紹這四個指令。

       [1]RewriteEngine: 就是是否使用 Rewrite 模式的開關, 使用就設置成 on, 否則設置成 off。

       [2]RewriteBase:如果使用目錄別名的話就需要設置這個指令,假設一個網站目錄使用了別名操作: RewriteBase /ceshi   /123/456 那麼當客戶端訪問/ceshi/index.html 文件時是相當於訪問 /123/456/index.html。

       [3]RewriteCond:指令定義一條規則條件。在一條RewriteRule指令前面可能會有一條或多條RewriteCond指令,只有當自身的模板(pattern)匹配成功且這些條件也滿足時規則才被應用於當前URL處理。注意,RewriteCond 指令後面可帶 Flag, 現在只要2個可用, 一個是 NC(不區分大小寫的意思), 一個是 OR(連接下一個條件)。這裏對Rewritecond的正則匹配函數進行簡單說明。

第一個: ! 表示否的意思. 比如一個條件: 判斷訪問此頁面的上一頁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完成的, 因此需要小心使用這個功能以降低服務器的性能。

        [4]RewriteRule:是一個簡單的命令告訴mod_rewrite這個模塊如何去重寫,關鍵的地方在於可以在模式和替換中使用正則表達式來匹配相應的字符,正則表達式的廣泛的靈活性能將動態的URL轉換成各式各樣的符合要求的靜態URL。

5、FLAG_參數

C|chain
C|chain 意思: 字符 'C' 或者 字符串 'chain' 表示出了該行重寫規則外還要有其他的重寫規則, 相當於通常程序語言的 與符號 '&' , 如果第一條規則條匹配的話進行下一項條件匹配. 如果第一條或者中間一條匹配不成功. 在其後的都會被跳過.
 
CO|cookie
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 意思: 字符 'E' 或者 字符串 'env' 表示你可以設置一個環境變量. 注意一下變量在這個規則運行後生效.
看一個簡單的例子, 就是apache在記錄日誌的時候不記錄圖片的讀取記錄. 那麼下面的規則就有用了.
RewriteRule \.(png|gif|jpg) - [E=image:1]
CustomLog logs/access_log combined env=!image
 
F|forbidden
F|forbidden 意思: 字符 'F' 或者 字符串 'forbidden' 表示禁止訪問. Apache服務器會返回403禁止訪問狀態碼給客戶端.
下面的規則表示獲取或者下載 exe程序文件是被顯示禁止訪問.
RewriteRule \.exe - [F]
 
G|gone
G|gone 意思: 字符 'G' 或者 字符串 'gone' 表示服務器響應狀態碼爲:410 通常使用該標誌的時候 target 目標值設置成 "-" 被請求的資源是有效的.
下面的例子表示舊的資源是有效的. 並且不在乎大小寫.
RewriteRule oldproduct - [G,NC]
 
H|handler
H|handler 意思: 字符 'H' 或者 字符串 'handler' 表示強制使用某類型處理程序處理被請求的資源. 比如請求一些不帶後綴的文件的時候. 下面的列子表示當請求的URL裏沒有帶'.'的時候, 強制使用PHP來處理這類的請求.
RewriteRule !\. - [H=application/x-httpd-php]
 
L|last
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 意思: 字符 'N' 或者 字符串 'next' 表示重新回到規則頂部重複執行. 一般在極端情況下用這個標誌. 相當於一個while循環, 知道匹配失敗時返回. 下面的例子表示把請求地址中的所有A字符替換成B字符.
RewriteRule (.*)A(.*) $1B$2 [N]
 
NC|nocase
NC|nocase 意思: 字符 'NC' 或者 字符串 'nocase' 表示請求的規則部分不區分大小寫. 類似正則式裏的/xxx/i 模式.
RewriteRule (.*\.(jpg|gif|png))$ http://images.test.com$1 [P,NC]
 
NE|noescape
NE|noescape 意思: 字符 'NE' 或者 字符串 'noescape' 表示不對URL中的特殊字符進行 hexcode 轉碼.看下面的例子:
RewriteRule ^/share/(.+) /goShare.html#$1 [NE,R]
上面的例子表示所有請求 /share/xxx.xx的請求都會被定向到/goShare.html文件上. 並且後面的部分作爲一個#後面的值. 如果不加NE標誌的話, #將被轉義成 %23 這樣就造成 404 錯誤了.
 
NS|nosubreq
NS|nosubreq 意思: 字符 'NS' 或者 字符串 'nosubreq' 表示只用於不是內部子請求.比如,在mod_include試圖搜索可能的目錄默認文件(index.xxx)時, Apache會內部地產生子請求。對子請求,它不一定有用的,而且如果整個規則集都起作用,它甚至可能會引發錯誤。所以,可以用這個標記來排除某些規則。根據你的需要遵循以下原則: 如果你使用了有CGI腳本的URL前綴,以強制它們由CGI腳本處理,而對子請求處理的出錯率(或者開銷)很高,在這種情況下,可以使用這個標記。
 
P|proxy
P|proxy 意思: 字符 'P' 或者 字符串 'proxy' 標誌需要模塊 mod_proxy 支持, 類似一個分發器網關的作用.比如網站的所有圖片想用單獨的一臺服務器來運行. 那麼先前的代碼裏的圖片請求的時候, 直接定向到圖片服務器去.
RewriteRule (.*)\.(jpg|gif|png) http://images.example.com$1.$2 [P]
使用[P]標誌, 意味着使用了[L]標誌, 因爲使用該標誌後馬上就重定向到新地址了. 後面的重寫規則會被忽略掉.
 
PT|passthrough
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 意思: 字符 '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 意思: 字符 'R' 或者 字符串 'redirect' 表示進行重定向, 狀態碼在300-399裏隨機出, 默認是 302 重定向.通常和標誌L一起使用. 使用模式: [R[=302]]
 
S|skip
T|type 意思: 字符 '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 意思: 字符 'T' 或者 字符串 'type' 表示爲apache設置特定請求的響應類型. 也就是常說的 MIME type,比如一個perl腳本. 希望給客戶端顯示文本源碼, 那麼可以這樣做:
RewriteRule \.pl$ - [T=text/plain]
或者你的服務器上的文件沒有設置擴展名. 那麼可以通知重寫添加該文件的類型. 方便客戶端顯示.
RewriteRule IMG - [T=image/jpg]

6、簡單的幾個案例

例子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]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章