(轉)Apache?Rewrite?詳解

(轉)Apache Rewrite 詳解

參考文檔:http://man.chinaunix.net/newsoft/ApacheManual/mod/mod_rewrite.html

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 的服務器變量信息. 在進入重寫實戰之前. 有些小細節了解一下是很又必要的.
首先一點. 如果在重寫規則的正則里要使用特殊字符的時候需要在該特殊字符前帶一個轉義字符: 反斜杠, 比如匹配一個百分號:%, 那么正確的寫法就該是: \%, 其他的特殊字符均按此寫法.
http://httpd.apache.org/docs/2.2/mod/core.html#allowencodedslashes
正反斜模杠
(轉)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可以由你任意擺布.
重寫還又很多高級功能, 這個需要自己慢慢的研究了. 特別關于負載均衡, 反向代理等其他很多有意思的高級功能可以慢慢去玩了. 本篇就到此為止了.


轉載于:https://www.cnblogs.com/lixuebin/p/10814313.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/256434.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/256434.shtml
英文地址,請注明出處:http://en.pswp.cn/news/256434.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python輪廓函數的使用

在圖像的處理中有時候需要對圖像中的目標區域提出出輪廓 讀取圖像 調用OpenCV的庫使用cv.imread()來讀取圖像。 圖像為 灰度化 二值化 提取輪廓時&#xff0c;圖像一般都是二值化后的圖像。在本次程序中選用cv2.THRESH_BINARY的二值化方式。即將大于閾值的部分設定為255&am…

Intent Bundle頁面跳轉信息的傳遞

MainActivity LoginActivity LoginLayout 轉載于:https://www.cnblogs.com/xiaolei121/p/5846644.html

超易懂數據庫范式

那些數據庫的書介紹的數據庫范式&#xff0c;實在是晦澀難懂&#xff0c;我在這里給出一個通俗的描述&#xff1a;1NF&#xff1a;一個table中的列是不可再分的&#xff08;即列的原子性&#xff09;2NF&#xff1a;一個table中的行是可以唯一標示的&#xff0c;&#xff08;即…

機器學習——支持向量機SVM之非線性模型(原問題轉化為對偶問題)

目錄 一、復習&#xff08;原問題、對偶問題、KKT條件、凸函數&#xff09; 二、將最優化問題標準化為原問題&#xff08;嚴格轉化為標準形式&#xff09; 1、原最優化問題 2、標準化后的問題 三、轉化為對偶問題&#xff08;注意變量的對應關系&#xff09; 四、對對偶問…

靜止的單攝像機無法得到像點的三維坐標詳解

我們知道在機器視覺中通常要使用的搭建的視覺測量系統對一個物體的尺寸、形變、以及三維形貌進行測量。一般按照攝像機的個數以及組成部分分為三類測量方法。分別為單目測量、雙目&#xff08;大于2為多目&#xff09;測量、以及結構光測量。 單目測量系統 顧名思義單目就指的…

一個比較笨的全文搜索的例子(分析結構用)-模糊查找

1 2 3 4 --在所有的char類型的列中模糊查找某個值。5 --**注意預先切換到當前的數據庫中。6 DECLARE TABLE_CATALOG NVARCHAR(MAX)--數據庫名7 ,TABLE_SCHEMA NVARCHAR(MAX)--架構名8 ,TABLE_NAME NVARCHAR(MAX)--表名9 ,COLUMN_NAME NVARCHAR(MAX)--列名 10 ,SQL N…

未能加載文件或程序集“Poderosa.Core

https://github.com/poderosaproject/poderosa上下載的一個開源工程&#xff0c;程序是在VS2012上編譯的&#xff0c;然后VS2015轉換后編譯失敗&#xff0c;報“未能加載文件或程序集“Poderosa.Core......”的錯誤 猜測是轉換的時候引用丟失了&#xff0c;于是添加引用 F:\...…

個人閱讀作業Week7

上了大學之后其實就沒有很多時間去讀書了&#xff0c;與其說軟工作業時給我們布置了一些任務&#xff0c;但是也是在另一方面讓我們得到了更多的知識的填補&#xff0c;因為平常能夠接觸的書籍很少&#xff0c;平常自己也是一個很不愛看書的人&#xff0c;所以我覺得這樣的作業…

圖像的像素、分辨率、像元尺寸、大小、清晰度的關系

圖像的像素&#xff1a; 圖像是由像素所組成的&#xff0c;像素的多少表明攝像機所含有的感光元件的多少。像素是指一張圖像中所有的像素數之和。 圖像分辨率&#xff1a; 是指表達方式也為“水平像素數垂直像素數” 像元尺寸&#xff1a; 是指一個像素在長和寬方向上所代表的實…

機器學習——支持向量機SVM實例(兵王問題,SVM求解步驟以及思路,不求解不編程)

目錄 一、問題描述&#xff08;兵王問題&#xff09; 二、步驟 1、獲得數據 2、樣本劃分&#xff08;訓練樣本和測試樣本&#xff09; 3、訓練樣本得到SVM模型 ? 1&#xff09;數據處理 2&#xff09;訓練樣本和測試樣本歸一化 3&#xff09;選擇核函數和調參 4&#…

單攝像機對于二維平面的測量

二維平面測量 首先我們應該知道什么是二維平面&#xff0c;二維平面簡單的說就是只含有x,y坐標系的平面&#xff0c;在z軸上沒有當量。這種一般出現在對于一個平面的寬度&#xff0c;長度&#xff0c;變形的測量&#xff0c;一般應用較多的場合是對一個規則的機械零件進行尺寸…

十六進制,輸出的時候怎樣控制所輸出字母的大小寫。

the first&#xff1a;printf("%x",10);printf("%X",10); 可以用x的大小寫來控制&#xff0c;所輸出字符的大小寫&#xff0c;真是一個巧妙的技能。轉載于:https://www.cnblogs.com/A-FM/p/4970114.html

Django的安裝

Django是Python的一款Web開源框架&#xff0c;所以Django是依賴于Python的&#xff0c;首先要安裝Python。 Python安裝 官網地址&#xff1a;http://www.python.org/download/ 在安裝Python的時候&#xff0c;會有人糾結&#xff0c;是要安裝Python2還是Python3呢&#xff1f;其…

機器學習——支持向量機SVM之多分類問題

目錄 方法1&#xff1a;改造目標函數與限制條件 方法2&#xff1a;一類對其他類&#xff08;類數為N&#xff0c;需要建立N個SVM模型&#xff09; 情形1&#xff1a;多個SVM模型結果交集得出確切歸類 情形2&#xff1a;多個SVM模型結果交集沒有得出確切歸類 方法3&#xff…

python3版本無法加載reload解決辦法NameError: name 'reload' is not defined

很多人在運行八點法求基礎矩陣問題時&#xff0c;都會遇到NameError: name ‘reload’ is not defined的錯誤 只需在最前面加上from imp import reload即可

hdu 2612 Find a way(bfs)

Problem DescriptionPass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Ningbo one year, yifenfei have many people to meet. Especially a good friend Merceki. Yifenfei’s home is at the countryside, but Merceki’s home is in …

定義類或對象

學習總結&#xff1a; 工廠方式 原始的方式&#xff08;對象創建后動態定義對象的屬性&#xff09; var oCar new Object; oCar.color "blue"; oCar.doors 4; oCar.mpg 25; oCar.showColor function() {alert(this.color); };創建對象 car&#xff0c;屬性&…

七橋問題

怎么不重復地走完連接兩座島和陸地的七座橋&#xff1f; 簡化為以下&#xff1a; 答案是不能走完的。 奇點&#xff1a;這個點有奇數條線匯聚于此 偶點&#xff1a;這個點有奇數條線匯聚于此 七橋問題——一筆畫問題 若一個圖形全部是偶點或者只有2個奇點&#xff08;沒有…

office2016打開PPT出現解決VBE6EXT.OLB不能被加載問題的解決辦法

第一步 打開路徑C:\Program Files (x86)\Microsoft Office\root\VFS\ProgramFilesCommonX86\Microsoft Shared\VBA。找到VBA只要是默認安裝路徑均一樣。 第二步 打開VBA6找到VBE6EXT.OLB將其復制到VBA7.1中。 第三步 打開VBA7.1找到VBE7.DLL將其復制到VBA6中。 第四步…