Apache的Mod_rewrite學習(RewriteRule重寫規則的語法) 轉

RewriteRule
Syntax: RewriteRule Pattern Substitution [flags] 
一條RewriteRule指令,定義一條重寫規則,規則間的順序很是重要。對Apache1.2及之後的版本,模板(pattern)是一個 POSIX正則式,用以匹配當前的URL。當前的URL不必定是用記最初提交的URL,由於可能用一些規則在此規則前已經對URL進行了處理。  Apache的Mod_rewrite學習(RewriteRule重寫規則的語法) - dawnsword - 理想與現實
對mod_rewrite來講,!是個合法的模板前綴,表示「非」的意思,這對描述「不知足某種匹配條件」的狀況很是方便,或用做最後一條默認規則。當使用!時,不能在模板中有分組的通配符,也不能作後向引用。
當匹配成功後,Substitution會被用來替換相應的匹配,它除了能夠是普通的字符串之外,還能夠包括: 
1. $N,引用RewriteRule模板中匹配的相關字串,N表示序號,N=0..9 
2. %N,引用最後一個RewriteCond模板中匹配的數據,N表示序號 
3. %{VARNAME},服務器變量 
4. ${mapname:key|default},映射函數調用
這些特殊內容的擴展,按上述順序進行。
一個URL的所有相關部分都會被Substitution替換,並且這個替換過程會一直持續到全部的規則都被執行完,除非明確地用L標誌中斷處理過程。
當susbstitution有」-」前綴時,表示不進行替換,只作匹配檢查。
利用RewriteRule,可定義含有請求串(Query String)的URL,此時只需在Sustitution中加入一個?,表示此後的內容放入QUERY_STRING變量中。若是要清空一個 QUERY_STRING變量,只須要以?結束Substitution串便可。
若是給一個Substitution增長一個http://thishost[:port]的前綴,則mod_rewrite會自動將此前綴去掉。所以,利用http://thisthost作一個無條件的重定向到本身,將難以奏效。要實現這種效果,必須使用R標誌。
Flags是可選參數,當有多個標誌同時出現時,彼此間以逗號分隔。
1. 'redirect|R [=code]' (強制重定向)
給當前的URI增長前綴http://thishost[:thisport]/, 從而生成一個新的URL,強制生成一個外部重定向(external redirection,指生的URL發送到客戶端,由客戶端再次以新的URL發出請求,雖然新URL仍指向當前的服務器). 若是沒有指定的code值,則HTTP應答以狀態值302 (MOVED TEMPORARILY),若是想使用300-400(不含400)間的其它值能夠經過在code的位置以相應的數字指定,也能夠用標誌名指定: temp (默認值), permanent, seeother.
注意,當使用這個標誌時,要確實substitution是個合法的URL,這個標誌只是在URL前增長http://thishost[:thisport]/前綴而已,重寫操做會繼續進行。若是要當即將新URL重定向,用L標誌來中重寫流程。 
2. 'forbidden|F' (強制禁止訪問URL所指的資源)
當即返回狀態值403 (FORBIDDEN)的應答包。將這個標誌與合適的RewriteConds 聯合使用,能夠阻斷訪問某些URL。 
3. 'gone|G' (強制返回URL所指資源爲不存在(gone))
當即返回狀態值410 (GONE)的應答包。用這個標誌來標記URL所指的資源永久消失了. 
4. # 'proxy|P' (強制將當前URL送往代理模塊(proxy module))
這個標誌,強制將substitution看成一個發向代理模塊的請求,並當即將共送往代理模塊。所以,必須確保substitution串是一個合法的URI (如, 典型的狀況是以http://hostname開頭),不然會從代理模塊獲得一個錯誤. 這個標誌,是ProxyPass指令的一個更強勁的實現,將遠程請求(remote stuff)映射到本地服務器的名字空間(namespace)中來。
注意,使用這個功能必須確保代理模塊已經編譯到Apache 服務器程序中了. 能夠用「httpd -l 」命令,來檢查輸出中是否含有mod_proxy.c來確認一下。若是沒有,而又須要使用這個功能,則須要從新編譯``httpd''程序並使用 mod_proxy有效。 
5. 'last|L' (最後一條規則)
停止重寫流程,再也不對當前URL施加更多的重寫規則。這至關於perl的last命令或C的break命令。 
6. 'next|N' (下一輪)
從新從第一條重寫規則開始執行重寫過程,新開的過程當中的URL不該當與最初的URL相同。 這至關於Perl的next命令或C的continue命令. 千萬當心不要產生死循環。 
7. # 'chain|C' (將當前的規則與其後續規則綑綁(chained))
當規則匹配時,處理過程與沒有綑綁同樣;若是規則不匹配,則綑綁在一塊兒的後續規則也不在檢查和執行。 
8. 'type|T=MIME-type' (強制MIME類型)
強制將目標文件的MIME-type爲某MIME類型。例如,這可用來模仿mod_alias模塊對某目錄的ScriptAlias指定,經過強制將該目錄下的全部文件的類型改成 「application/x-httpd-cgi」. 
9. 'nosubreq|NS' (used only if no internal sub-request )
這個標誌強制重寫引擎跳過爲內部sub-request的重寫規則.例如,當mod_include試圖找到某一目錄下的默認文件時 (index.xxx),sub-requests 會在Apache內部發生. Sub-requests並不是老是有用的,在某些狀況下若是整個規則集施加到它上面,會產生錯誤。利用這個標誌可排除執行一些規則。 
10. 'nocase|NC' (模板不區分大小寫)
這個標誌會使得模板匹配當前URL時忽略大小寫的差異。 
11. 'qsappend|QSA' (追加請求串(query string))
這個標誌,強制重寫引擎爲Substitution的請求串追加一部分串,則不是替換掉原來的。藉助這個標誌,可使用一個重寫規則給請求串增長更多的數據。 
12. 'noescape|NE' (不對輸出結果中的特殊字符進行轉義處理)
一般狀況下,mod_write的輸出結果中,特殊字符(如'%', '$', ';', 等)會轉義爲它們的16進制形式(如分別爲'%25', '%24', and '%3B')。這個標誌會禁止mod_rewrite對輸出結果進行此類操做。 這個標誌只能在 Apache 1.3.20及之後的版本中使用。 
13. 'passthrough|PT' (經過下一個處理器)
這個標誌強制重寫引擎用 filename字段的值來替換內部request_rec數據結構中uri字段的值。. 使用這個標誌,可使後續的其它URI-to-filename轉換器的Alias、ScriptAlias、Redirect等指令,也能正常處理 RewriteRule指令的輸出結果。用一個小例子來講明它的語義:若是要用mod_rewrite的重寫引擎將/abc轉換爲/def,而後用 mod_alas將/def重寫爲ghi,則要:
RewriteRule ^/abc(.*) /def$1 [PT]
Alias /def /ghi
如 果PT標誌被忽略,則mod_rewrite也能很好完成工做,若是., 將 uri=/abc/... 轉換爲filename=/def/... ,徹底符合一個URI-to-filename轉換器的動做。接下來 mod_alias 試圖作 URI-to-filename 轉換時就會出問題。
注意:若是要混合都含有URL-to-filename轉換器的不一樣的模塊的指令,必須用這個標誌。最典型的例子是mod_alias和mod_rewrite的使用。 
14. 'skip|S=num' (跳事後面的num個規則)
當前規則匹配時,強制重寫引擎跳事後續的num個規則。用這個能夠來模仿if-then-else結構:then子句的最後一條rule的標誌是skip=N,而N是else子句的規則條數。 
15. 'env|E=VAR:VAL' (設置環境變量)
設置名爲VAR的環境變量的值爲VAL,其中VAL中能夠含有正則式的後向引用($N或%N)。這個標誌可使用屢次,以設置多個環境變量。這兒設置的 變量,能夠在多種狀況下被引用,如在XSSI或CGI中。另外,也能夠在RewriteCond模板中以%{ENV:VAR}的形式被引用。 
16.html

注意:必定不要忘記,在服務器範圍內的配置文件中,模板(pattern)用以匹配整個URL;而在目錄範圍內的配置文件中,目錄前綴老是被自動去 掉後再進行模板匹配的,且在替換完成後自動再加上這個前綴。這個功能對不少種類的重寫是很是重要的,由於若是沒有去前綴,則要進行父目錄的匹配,而父目錄 的信息並非總能獲得的。一個例外是,當substitution中有http://打頭時,則再也不自動增長前綴了,若是P標誌出現,則會強制轉向代理。
注 意:若是要在某個目錄範圍內啓動重寫引擎,則須要在相應的目錄配置文件中設置「RewriteEngine on」,且目錄的「Options FollowSymLinks」必須設置。若是管理員因爲安全緣由沒有打開FollowSymLinks,則不能使用重寫引擎。apache

--------------------------------------------------------------------------------------------

Apache - 模塊 - mod_rewrite - RewriteCond - 經過檢查HTTP_REFERER避免靜態圖片盜鏈對性能有嚴重影響


Apache 重寫規則的常見應用 (rewrite) 

一:目的瀏覽器

      本文旨在提供如何用Apache重寫規則來解決一些常見的URL重寫方法的問題,經過常見的 
實例給用戶一些使用重寫規則的基本方法和線索。安全

      二:爲何須要用重寫規則? 
一個網站,若是是長期須要放在internet上提供服務,一定會有不斷地更新和維護,如臨 
時轉移到其它服務器進行維護,從新組織目錄結構,變換URL甚至改變到新的域名等等, 
而爲了讓客戶不會所以受到任何影響,最好的方法就是使用Apache Rewrite Rule(重寫 
規則)。服務器

      三: 重寫規則的做用範圍 
1) 可使用在Apache主配置文件httpd.conf中 
2) 可使用在httpd.conf裏定義的虛擬主機配置中 
3) 可使用在基本目錄的跨越配置文件.htaccess中數據結構

      四:重寫規則的應用條件 
只有當用戶的WEB請求最終被導向到某臺WEB服務器的Apache後臺,則這臺WEB服務器接受 
進來的請求,根據配置文件該請求是主配置仍是虛擬主機,再根據用戶在瀏覽器中請求的 
URI來配對重寫規則而且根據實際的請求路徑配對.htaccess中的重寫規則。最後把請求 
的內容傳回給用戶,該響應可能有兩種:app

      1) 對瀏覽器請求內容的外部重定向(Redirect)到另外一個URL。 
讓瀏覽器再次以新的URI發出請求(R=301或者R=302,臨時的或是永久的重定向) 
如:一個網站有正規的URL和別名URL,對別名URL進行重定向到正規URL,或者網站改換 
成了新的域名 
則把舊的域名重定向到新的域名(Redirect)dom

      2) 也多是由Apache內部子請求代理產生新的內容送回給客戶[P,L] 
這是Apache內部根據重寫後的URI內部經過代理模塊請求內容並送回內容給客戶,而客戶 
端瀏覽器並 
不知道,瀏覽器中的URI不會被重寫。但實際內容被Apache根據重寫規則後的URI獲得。 
如:在公司防火牆上運行的Apache啓動這種代理重寫規則,代理對內部網段上的WEB服務 
器的請求。ide

      五:重寫規則怎樣工做? 
咱們假定在編譯Apache時已經把mod_rewrite編譯成模塊,確信你的httpd.conf中有 
LoadModule rewrite_module libexec/mod_rewrite.so 
而且在Addmodule中有 
Addmodule mod_rewrite.c 
則可使用重寫規則。 
當外部請求來到Apache,Apache調用重寫規則中的定義來重寫由用戶瀏覽器指定請求的 
URI,最後被重寫的URI若是是重定向,則送由瀏覽器做再一次請求;若是是代理則把重寫 
後的URI交給代理模塊請求最終的內容(Content),最後把內容送回給瀏覽器。函數

      六: 什麼時候使用.htaccess中的重寫規則定義? 
假如你對你的的網站內容所在的服務器沒有管理員權限,或者你的網站放在ISP的服務器 
上託管等等條件下,你沒法改寫主配置文件,然而你能夠對你的WEB站點內容所在的目錄 
有寫權限,則你能夠設置本身的.htaccess 
文件達到一樣的目的。但你須要肯定主配置文件中對你的網站所在的目錄定義了下面的內 
容:

      Options Indexes FollowSymLinks 
AllowOverride all

      不然你的.htaccess不會工做。

      七: 應用舉例 
假定Apache被編譯安裝在主機192.168.1.56的/usr/local/apache/ 目錄下面,咱們編 
譯進了重寫和代理模塊。

      1) 隱藏Apache下的某個目錄,使得對該目錄的任何請求都重定向到另外一個文件。

      a> httpd.conf的實現方法

      咱們放下面的部分到/usr/local/apache/conf/httpd.conf


      options Indexes followsymlinks 
allowoverride all 
rewriteengine on 
rewritebase / 
rewriterule ^(.*)$ index.html.en [R=301]


      注:rewriteengine on 爲重寫引擎開關,若是設爲off,則任何重寫規則定義將不被應 
用,該開關的另外一好處就是若是爲了臨時拿掉重寫規則,則改成off再重啓動Apache即 
可,沒必要將下面一條條的重寫規則註釋掉。 
rewritebase / 的做用是若是在下面的rewriterule定義中被重寫後的部分(此處爲文件 
名index.html.en)前面沒有/,則是相對目錄,相對於這個rewritebase後面的定義也就 
是/usr/local/apache/htdocs/index.html.en,不然,若是此處沒有rewritebase /這 
一項,則被重寫成 
http://192.168.1.56/usr/local/apache/htdocs/manual/index.html.en ,顯然是 
不正確的。

      不過這裏咱們也能夠不用rewritebase / , 而改成 
rewriteengine on 
rewriterule ^(.*)$ /index.html.en [R=301] 
或者 
rewriteengine on 
rewriterule ^(.*)$ http://192.168.1.56/index.html.en [R=301]

      b> .htaccess的實現方法

      咱們先放下面的部分到httpd.conf


      options Indexes followsymlinks 
allowoverride all


      而後放下面的部分到/usr/local/apache/htdocs/manual/.htaccess中 
rewriteengine on 
rewritebase / 
rewriterule ^(.*)$ index.html.en [R=301]

      注:對文件.htaccess所做的任何改動不須要重啓動Apache.

      問:要是把這個manual目錄重定向到用戶jephe的本身的主目錄呢? 
用下面的.htaccess方案。 
rewriteengine on 
rewritebase /~jephe/ 
rewriterule ^(.*)$ $1 [R=301]

      則對manual目錄下任何文件的請求被重定向到~jephe目錄下相同文件的請求。

      2) 轉換www.username.domain.com的對於username的主頁請求爲 
www.domain.com/username

      對於HTTP/1.1的請求包括一個Host: HTTP頭,咱們能用下面的規則集重寫 
http://www.username.domain.com/anypath 到 /home/username/anypath

      Rewriteengine on 
rewritecond %{HTTP_HOST} ^www\.[^.]+\.host\.com$ 
rewriterule ^(.+) %{HTTP_HOST}$1 [C] 
rewriterule ^www\.([^.]+)\.host\.com(.*) /home/$1$2

      注: 
rewritecond 條件重寫規則,當知足後面定義的條件後纔會應用下面的重寫規則, 
rewritecond有各類變量 
,請查閱相關文檔。

      3) 防火牆上的重寫規則代理內部網段上服務器的請求。

      NameVirtualhost 1.2.3.4


      servername www.domain.com 
rewriteengine on 
proxyrequest on 
rewriterule ^/(.*)$ http://192.168.1.3/$1 [P,L]


      注:當外部瀏覽器請求www.domain.com時被解析到IP地址1.2.3.4 ,Apache 交出 
mod_rewrite處理轉換成 
http://192.168.1.3/$1後再交由代理模塊mod_proxy獲得內容後傳送回用戶的瀏覽器。


      4) 基本預先設定的轉換MAP表進行重寫 rewritemap

      轉換www.domain.com/{countrycode}/anypath 到Map表中規定的URI,上面是虛擬主機 
中的定義

      rewritelog /usr/local/apache/logs/rewrite.log 
rewriteloglevel 9

      rewriteengine on 
proxyrequest on 
rewritemap sitemap txt:/usr/local/apache/conf/rewrite.map 
rewriterule ^/([^/]+)+/(.*)$ http://%{REMOTE_HOST}::$1 [C] 
rewriterule (.*)::([a-z]+)$ ${sitemap:$2|http://h.i.j.k/} [R=301,L]

      文件/usr/local/apache/conf/rewrite.map的內容以下:

      sg http://a.b.c.d/ 
sh http://e.f.g.h/

      注: 當用戶請求http://www.domain.com/sg/anypath時被重寫爲 
http://a.b.c.d/anypath . 當須要調試時請用rewritelog and rewriteloglevel 9聯合,9爲最大即獲得最多的調試 信息 最小爲1,最小的調試信息,默認爲0,沒有調試信息。 sitemap的語法是${sitemap: LookupKey | Defaultvalue} ,有些書上把$寫成了%是錯 誤的。

相關文章
相關標籤/搜索