麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 網(wǎng)站 > Apache > 正文

apache重寫規(guī)則詳解

2024-08-27 18:22:17
字體:
供稿:網(wǎng)友

Rewirte主要的功能就是實現(xiàn)URL的跳轉(zhuǎn)和隱藏真實地址,基于Perl語言的正則表達(dá)式規(guī)范。平時幫助我們實現(xiàn)擬靜態(tài),擬目錄,域名跳轉(zhuǎn),防止盜鏈等。本文將針對mod_rewrite和URL匹配的技術(shù)細(xì)節(jié),以及RewriteCond與RewriteRule 指令格式進(jìn)行探討。

Rewirte模塊內(nèi)部處理

Rewirte模塊的內(nèi)部處理極為復(fù)雜,但是為了使一般用戶避免犯低級錯誤,也讓管理員能充分利用其功能,在此仍然做一下說明。

Rewirte模塊API階段

首先,你必須了解Apache是分若干階段來處理HTTP請求的。Apache API對每個階段都提供了一個hook程序。mod_rewrite使用兩個hook程序:其一,從URL到文件名的轉(zhuǎn)換hook(用在讀取HTTP請求之后、授權(quán)開始之前); 其二,修正hook(用在授權(quán)階段和讀取目錄級配置(.htaccess)之后、內(nèi)容處理器激活之前)。

所以,Apache收到一個請求并且確定了響應(yīng)主機(jī)(或虛擬主機(jī))之后,重寫引擎即開始處理服務(wù)器級配置中的所有mod_rewrite指令(此時處于從URL到文件名轉(zhuǎn)換的階段),此階段完成后,最終的數(shù)據(jù)目錄便確定了。接下來進(jìn)入修正程序段并觸發(fā)目錄級配置中的mod_rewrite指令。這兩個階段并不是涇渭分明的,但都實施了把URL重寫成新的URL或者文件名。雖然API最初不是為此目的而設(shè)計的,但是現(xiàn)在它已經(jīng)成為了API的一種用途。記住以下兩點,會有助于更好地理解:

1、雖然mod_rewrite可以將URL重寫為新的URL或文件名,甚至將文件名重寫為新的文件名,但是之前的API只提供從URL到文件名的hook。在Apache 2.0中,增加了兩個丟失的hook以使得處理過程更加清晰。不過這樣做并沒有給用戶帶來麻煩,用戶只需記住這樣一個事實:借助從URL到文件名的hook比最初API設(shè)計的目標(biāo)功能更強(qiáng)大。

2、令人難以置信的是,mod_rewrite還提供了目錄級的URL操作(.htaccess文件),而這些文件必須在將URL轉(zhuǎn)換成文件名之后才會被處理(這是必須的,因為.htaccess存在于文件系統(tǒng)中)。換句話說,根據(jù)API階段,這時再處理任何URL操作已經(jīng)太晚了。為了解決這個”雞和蛋”的問題,mod_rewrite使用了一個小技巧:在進(jìn)行一個目錄級的URL/文件名操作時,先把文件名重寫回相應(yīng)的URL(通常這個操作是不可行的,但是參考下面的RewriteBase指令就能明白它是怎么實現(xiàn)的了),然后,對這個新的URL建立一個新的內(nèi)部的子請求,再重新開始API階段的執(zhí)行。

另外,mod_rewrite盡力使這些復(fù)雜的操作對用戶透明。但仍須記住:服務(wù)器級的URL操作速度快而且效率高,而目錄級的操作由于這個”雞和蛋”的問題速度較慢而且效率也低。但從另一個側(cè)面看,這卻是mod_rewrite得以為一般用戶提供(局部限制的)URL操作的唯一方法。

Rewirte模塊規(guī)則集的處理

當(dāng)mod_rewrite在這兩個API階段中開始執(zhí)行時,它會讀取配置結(jié)構(gòu)中配置好的 (或者是在服務(wù)啟動時建立的服務(wù)器級的,或者是在遍歷目錄采集到的目錄級的)規(guī)則集,然后,啟動URL重寫引擎來處理(帶有一個或多個條件的)規(guī)則集。無論是服務(wù)器級的還是目錄級的規(guī)則集,都是由同一個URL重寫引擎處理,只是最終結(jié)果處理不同而已。

規(guī)則集中規(guī)則的順序是很重要的,因為重寫引擎是按一種特殊的順序處理的:逐個遍歷每個規(guī)則(RewriteRule指令),如果出現(xiàn)一個匹配條件的規(guī)則,則可能回頭遍歷已有的規(guī)則條件(RewriteCond指令)。由于歷史的原因,條件規(guī)則是前置的,所以控制流程略顯冗長。

URL首先與每個規(guī)則的Pattern匹配,如果匹配失敗,mod_rewrite將立即終止此規(guī)則的處理,繼而處理下一個規(guī)則。如果匹配成功,mod_rewrite將尋找相應(yīng)的規(guī)則條件,如果一個條件都沒有,則簡單地用Substitution構(gòu)造的新值來替換URL,然后繼續(xù)處理其他規(guī)則;但是如果條件存在,則開始一個內(nèi)部循環(huán)按其列出的順序逐個處理。對規(guī)則條件的處理有所不同:URL并不與模式進(jìn)行匹配,而是首先通過擴(kuò)展變量、反向引用、查找映射表等步驟建立一個TestString字符串,然后用它來與CondPattern匹配。如果匹配失敗,則整個條件集和對應(yīng)的規(guī)則失敗;如果匹配成功,則執(zhí)行下一個規(guī)則直到所有條件執(zhí)行完畢。如果所有條件得以匹配,則以Substitution替換URL,并且繼續(xù)處理。

RewriteCond指令格式

語法: RewriteCond TestString CondPattern [flags]

RewriteCond指令定義一條規(guī)則條件。在一條RewriteRule指令前面可能會有一條或多條RewriteCond指令,只有當(dāng)自身的模板(pattern)匹配成功且這些條件也滿足時規(guī)則才被應(yīng)用于當(dāng)前URL處理。

1、TestString是一個純文本的字符串,除了包含普通的字符外,還可以包括下列的可擴(kuò)展結(jié)構(gòu):

1)$N:RewriteRule后向引用,其中(0 <= N <= 9) 。$N引用緊跟在RewriteCond后面的RewriteRule中模板中的括號中的模板在當(dāng)前URL中匹配的數(shù)據(jù)。

2)%N:RewriteCond后向引用,其中(0 <= N <= 9) 。%N引用最后一個RewriteCond的模板中的括號中的模板在當(dāng)前URL中匹配的數(shù)據(jù)。

3)${mapname:key|default}:RewriteMap擴(kuò)展。

2、CondPattern是條件pattern, 即一個應(yīng)用于當(dāng)前實例TestString的正則表達(dá)式, 即TestString將會被計算然后與CondPattern匹配。作為一個標(biāo)準(zhǔn)的擴(kuò)展正則式,CondPattern有以下補(bǔ)充:

1)可以在模板串前增加一個!前綴,以用表示不匹配模板。但并不是所有的test都可以加!前綴。

2)CondPattern中可以使用以下特殊變量:

'>CondPattern’(大于) 將condPattern當(dāng)作一個普通字符串,將它和TestString進(jìn)行比較,當(dāng)TestString 的字符大于CondPattern為真。

‘=CondPattern’ (等于) 將condPattern當(dāng)作一個普通字符串,將它和TestString進(jìn)行比較,當(dāng)TestString 與CondPattern完全相同時為真.如果CondPattern只是 “” (兩個引號緊挨在一起) 此時需TestString 為空字符串方為真。

‘-d’ (是否為目錄) 將testString當(dāng)作一個目錄名,檢查它是否存在以及是否是一個目錄。

‘-f’ (是否是regular file) 將testString當(dāng)作一個文件名,檢查它是否存在以及是否是一個regular文件。

‘-s’ (是否為長度不為0的regular文件) 將testString當(dāng)作一個文件名,檢查它是否存在以及是否是一個長度大于0的regular文件。

‘-l’ (是否為symbolic link) 將testString當(dāng)作一個文件名,檢查它是否存在以及是否是一個 symbolic link。

‘-F’ (通過subrequest來檢查某文件是否可訪問) 檢查TestString是否是一個合法的文件,而且通過服務(wù)器范圍內(nèi)的當(dāng)前設(shè)置的訪問控制進(jìn)行訪問。這個檢查是通過一個內(nèi)部subrequest完成的, 因此需要小心使用這個功能以降低服務(wù)器的性能。

‘-U’ (通過subrequest來檢查某個URL是否存在) 檢查TestString是否是一個合法的URL,而且通過服務(wù)器范圍內(nèi)的當(dāng)前設(shè)置的訪問控制進(jìn)行訪問。這個檢查是通過一個內(nèi)部subrequest完成的, 因此需要小心使用這個功能以降低服務(wù)器的性能。

3、[flags]是第三個參數(shù),多個標(biāo)志之間用逗號分隔。

1)’nocase|NC’ (不區(qū)分大小寫)   在擴(kuò)展后的TestString和CondPattern中,比較時不區(qū)分文本的大小寫。注意,這個標(biāo)志對文件系統(tǒng)和subrequest檢查沒有影響.

2)’ornext|OR’ (建立與下一個條件的或的關(guān)系)   默認(rèn)的情況下,二個條件之間是AND的關(guān)系,用這個標(biāo)志將關(guān)系改為OR。例如: RewriteCond %{REMOTE_HOST} ^host1.* [OR] RewriteCond %{REMOTE_HOST} ^host2.* [OR] RewriteCond %{REMOTE_HOST} ^host3.* RewriteRule … 如果沒有[OR]標(biāo)志,需要寫三個條件/規(guī)則.

RewriteRule 指令

語法: RewriteRule Pattern Substitution [flags]

1) Pattern是一個作用于當(dāng)前URL的兼容perl的正則表達(dá)式. 這里的“當(dāng)前”是指該規(guī)則生效時的URL的值。

2) Substitution是,當(dāng)原始URL與Pattern相匹配時,用以替代(或替換)的字符串。

3) 此外,Substitution還可以追加特殊標(biāo)記[flags] 作為RewriteRule指令的第三個參數(shù)。 Flags是一個包含以逗號分隔的下列標(biāo)記的列表:

redirect|R [=code] (強(qiáng)制重定向 redirect)

以 http://thishost[:thisport]/(使新的URL成為一個URI) 為前綴的Substitution可以強(qiáng)制性執(zhí)行一個外部重定向。 如果code沒有指定,則產(chǎn)生一個HTTP響應(yīng)代碼302(臨時性移動)。如果需要使用在300-400范圍內(nèi)的其他響應(yīng)代碼,只需在此指定這個數(shù)值即可, 另外,還可以使用下列符號名稱之一: temp (默認(rèn)的), permanent, seeother. 用它可以把規(guī)范化的URL反饋給客戶端,如, 重寫“/~”為 “/u/”,或?qū)?u/user加上斜杠,等等。

注意: 在使用這個標(biāo)記時,必須確保該替換字段是一個有效的URL! 否則,它會指向一個無效的位置! 并且要記住,此標(biāo)記本身只是對URL加上 http://thishost[:thisport]/的前綴,重寫操作仍然會繼續(xù)。通常,你會希望停止重寫操作而立即重定向,則還需要使用’L’標(biāo)記.

forbidden|F (強(qiáng)制URL為被禁止的 forbidden)

強(qiáng)制當(dāng)前URL為被禁止的,即,立即反饋一個HTTP響應(yīng)代碼403(被禁止的)。使用這個標(biāo)記,可以鏈接若干RewriteConds以有條件地阻塞某些URL。

gone|G’(強(qiáng)制URL為已廢棄的 gone)

強(qiáng)制當(dāng)前URL為已廢棄的,即,立即反饋一個HTTP響應(yīng)代碼410(已廢棄的)。使用這個標(biāo)記,可以標(biāo)明頁面已經(jīng)被廢棄而不存在了.

proxy|P (強(qiáng)制為代理 proxy)

此標(biāo)記使替換成分被內(nèi)部地強(qiáng)制為代理請求,并立即(即, 重寫規(guī)則處理立即中斷)把處理移交給代理模塊。你必須確保此替換串是一個有效的(比如常見的以 http://hostname開頭的)能夠為Apache代理模塊所處理的URI。使用這個標(biāo)記,可以把某些遠(yuǎn)程成分映射到本地服務(wù)器名稱空間, 從而增強(qiáng)了ProxyPass指令的功能。

注意: 要使用這個功能,代理模塊必須編譯在Apache服務(wù)器中。 如果你不能確定,可以檢查“httpd -l”的輸出中是否有mod_proxy.c。 如果有,則mod_rewrite可以使用這個功能;如果沒有,則必須啟用mod_proxy并重新編譯“httpd”程序。

last|L (最后一個規(guī)則 last)

立即停止重寫操作,并不再應(yīng)用其他重寫規(guī)則。 它對應(yīng)于Perl中的last命令或C語言中的break命令。這個標(biāo)記可以阻止當(dāng)前已被重寫的URL為其后繼的規(guī)則所重寫。 舉例,使用它可以重寫根路徑的URL(’/’)為實際存在的URL, 比如, ‘/e/www/’.

next|N (重新執(zhí)行 next round)

重新執(zhí)行重寫操作(從第一個規(guī)則重新開始). 這時再次進(jìn)行處理的URL已經(jīng)不是原始的URL了,而是經(jīng)最后一個重寫規(guī)則處理的URL。它對應(yīng)于Perl中的next命令或C語言中的continue命令。 此標(biāo)記可以重新開始重寫操作,即, 立即回到循環(huán)的頭部。

但是要小心,不要制造死循環(huán)!

chain|C (與下一個規(guī)則相鏈接 chained)

此標(biāo)記使當(dāng)前規(guī)則與下一個(其本身又可以與其后繼規(guī)則相鏈接的, 并可以如此反復(fù)的)規(guī)則相鏈接。 它產(chǎn)生這樣一個效果: 如果一個規(guī)則被匹配,通常會繼續(xù)處理其后繼規(guī)則, 即,這個標(biāo)記不起作用;如果規(guī)則不能被匹配,則其后繼的鏈接的規(guī)則會被忽略。比如,在執(zhí)行一個外部重定向時, 對一個目錄級規(guī)則集,你可能需要刪除“.www” (此處不應(yīng)該出現(xiàn)“.www”的)。

type|T=MIME-type(強(qiáng)制MIME類型 type)

強(qiáng)制目標(biāo)文件的MIME類型為MIME-type。 比如,它可以用于模擬mod_alias中的ScriptAlias指令,以內(nèi)部地強(qiáng)制被映射目錄中的所有文件的MIME類型為“application/x-httpd-cgi”。

nosubreq|NS (僅用于不對內(nèi)部子請求進(jìn)行處理 no internal sub-request)

在當(dāng)前請求是一個內(nèi)部子請求時,此標(biāo)記強(qiáng)制重寫引擎跳過該重寫規(guī)則。比如,在mod_include試圖搜索可能的目錄默認(rèn)文件(index.xxx)時, Apache會內(nèi)部地產(chǎn)生子請求。對子請求,它不一定有用的,而且如果整個規(guī)則集都起作用,它甚至可能會引發(fā)錯誤。所以,可以用這個標(biāo)記來排除某些規(guī)則。

根據(jù)你的需要遵循以下原則: 如果你使用了有CGI腳本的URL前綴,以強(qiáng)制它們由CGI腳本處理,而對子請求處理的出錯率(或者開銷)很高,在這種情況下,可以使用這個標(biāo)記。

nocase|NC (忽略大小寫 no case)

它使Pattern忽略大小寫,即, 在Pattern與當(dāng)前URL匹配時,’A-Z’ 和’a-z’沒有區(qū)別。

qsappend|QSA (追加請求串 query string append)

此標(biāo)記強(qiáng)制重寫引擎在已有的替換串中追加一個請求串,而不是簡單的替換。如果需要通過重寫規(guī)則在請求串中增加信息,就可以使用這個標(biāo)記。

noescape|NE (在輸出中不對URI作轉(zhuǎn)義 no URI escaping)

此標(biāo)記阻止mod_rewrite對重寫結(jié)果應(yīng)用常規(guī)的URI轉(zhuǎn)義規(guī)則。 一般情況下,特殊字符(如’%’, ‘$’, ‘;’等)會被轉(zhuǎn)義為等值的十六進(jìn)制編碼。 此標(biāo)記可以阻止這樣的轉(zhuǎn)義,以允許百分號等符號出現(xiàn)在輸出中,如:

RewriteRule /foo/(.*) /bar?arg=P1=$1 [R,NE] 可以使’/foo/zed’轉(zhuǎn)向到一個安全的請求’/bar?arg=P1=zed’.

passthrough|PT (移交給下一個處理器 pass through)

此標(biāo)記強(qiáng)制重寫引擎將內(nèi)部結(jié)構(gòu)request_rec中的uri字段設(shè)置為 filename字段的值,它只是一個小修改,使之能對來自其他URI到文件名翻譯器的 Alias,ScriptAlias, Redirect 等指令的輸出進(jìn)行后續(xù)處理。舉一個能說明其含義的例子:如果要通過mod_rewrite的重寫引擎重寫/abc為/def,然后通過mod_alias使/def轉(zhuǎn)變?yōu)?ghi,可以這樣:

RewriteRule ^/abc(.*) /def$1 [PT]

Alias /def /ghi

如果省略了PT標(biāo)記,雖然mod_rewrite運(yùn)作正常, 即, 作為一個使用API的URI到文件名翻譯器,它可以重寫uri=/abc/…為filename=/def/…,但是,后續(xù)的mod_alias在試圖作URI到文件名的翻譯時,則會失效。

注意: 如果需要混合使用不同的包含URI到文件名翻譯器的模塊時, 就必須使用這個標(biāo)記。。混合使用mod_alias和mod_rewrite就是個典型的例子。

For Apache hackers

如果當(dāng)前Apache API除了URI到文件名hook之外,還有一個文件名到文件名的hook, 就不需要這個標(biāo)記了! 但是,如果沒有這樣一個hook,則此標(biāo)記是唯一的解決方案。 Apache Group討論過這個問題,并在Apache 2.0 版本中會增加這樣一個hook。

skip|S=num (跳過后繼的規(guī)則 skip)

此標(biāo)記強(qiáng)制重寫引擎跳過當(dāng)前匹配規(guī)則后繼的num個規(guī)則。 它可以實現(xiàn)一個偽if-then-else的構(gòu)造: 最后一個規(guī)則是then從句,而被跳過的skip=N個規(guī)則是else從句. (它和’chain|C’標(biāo)記是不同的!)

env|E=VAR:VAL (設(shè)置環(huán)境變量 environment variable)

此標(biāo)記使環(huán)境變量VAR的值為VAL, VAL可以包含可擴(kuò)展的反向引用的正則表達(dá)式$N和%N。 此標(biāo)記可以多次使用以設(shè)置多個變量。這些變量可以在其后許多情況下被間接引用,但通常是在XSSI (via ) or CGI (如 $ENV{’VAR’})中, 也可以在后繼的RewriteCond指令的pattern中通過%{ENV:VAR}作引用。使用它可以從URL中剝離并記住一些信息。

cookie|CO=NAME:VAL:domain[:lifetime[:path]] (設(shè)置cookie)

它在客戶端瀏覽器上設(shè)置一個cookie。 cookie的名稱是NAME,其值是VAL。 domain字段是該cookie的域,比如’.apache.org’, 可選的lifetime是cookie生命期的分鐘數(shù),可選的path是cookie的路徑。

案例:

city_map.txt的內(nèi)容:hangzhou 12  beijing 13

1、hangzhou.google.com/tianqi/20090401 跳轉(zhuǎn)到 www.google.com/service/detail.html?id=tianqi&date=20090401

  1. RewriteMap city-map txt:/etc/httpd/conf.d/map/city_map.txt    
  2. RewriteCond %{HTTP_HOST}    ^(.+).google.com$  
  3. RewriteRule ^/([w]+)/([d]+)$ /service/detail.html?id=$1&date=$2&c=${city-map:%1|%1} [PT,L]   

解釋:

%{HTTP_HOST}:取請求的域名

^(.+).google.com$:^,開頭;$結(jié)尾。.(逗號),除終止符外的任意字符。+,重復(fù)一個或一個以上的字符。,轉(zhuǎn)義字符。

^/([w]+)/([d]+)$:[],集合字符。w,數(shù)字或字母。d,數(shù)字。

$1:表示的是符合RewriteRule 中[w]+正則式的字符串,也就是tianqi。

$2:表示的是符合RewriteRule 中[d]+ 正則式的字符串,也就是20090401。

%1:表示的是符合RewriteCond 中.+正則式的字符串,也就是hangzhou。

${city-map:%1|%1}:表示取city-map中%1也就是hangzhou對應(yīng)的值,如果沒有則為%1也就是hangzhou。

2、能看出下面的規(guī)則是做了什么嗎?

  1. RewriteCond  %{HTTP_HOST} ^(.+).google.com$    
  2.      
  3. RewriteRule ^/([w]+)/([^-]+)-([^-]+)--([^-]+)-([^-]+)--([^-]+)-([^-]+)--([^-]+-[^-]+--[^-]+-[^-]+--[^-]+-[^-]+)$  /$1/$2=$3&$4=$5&$6=$7&$8   [C]     
  4.      
  5. RewriteCond  %{HTTP_HOST}  ^(.+).google.com$    
  6.      
  7. RewriteRule ^/([w]+)/([^-]+)-([^-]+)--([^-]+)-([^-]+)--([^-]+)-([^-]+)$     /service/list.html?frontCategoryId=${category-map:$1|0}&$2=$3&$4=$5&$6=$7&city=${city-map:%1|%1} [PT,L]   

解釋:

這個規(guī)則是想把-(中劃線)轉(zhuǎn)為=,把- -(兩條中劃線)轉(zhuǎn)為&。

[^-]:^在字符集合符號([])之內(nèi)表示反向選擇,之外表示行首,所以表示不以-開頭。

因為$N,N最大為9,所以使用了C,用第二條RewriteRule把第一條RewriteRule中的最后一個節(jié)點,即$8,進(jìn)行繼續(xù)轉(zhuǎn)換。

此外,rewrite規(guī)則中如果遇到中文,相當(dāng)有可能會出現(xiàn)亂碼問題,因為apache在rewrite時會做一次url解碼,這時jk進(jìn)行請求轉(zhuǎn)發(fā)時,就不會再是編碼后的字符串了。此種情況,可以在一開始就進(jìn)行兩次編碼(encode),或者在接收請求時先用ISO-8859-1取字節(jié)流,再使用UFT-8來new String。(new String(str.getBytes(”ISO-8859-1″),”UTF-8″))

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 九九热精品在线 | 黄色免费在线网址 | 久久综合婷婷香五月 | 国产免费小视频在线观看 | 久色精品视频 | 色戒在线版 | 国产一国产一级毛片视频 | 免费观看的毛片手机视频 | 日韩视频在线不卡 | h久久 | 天天夜干 | 97视频| 日本在线视 | 亚洲网站一区 | 黄色大片免费网站 | 欧美成人一区二区三区电影 | 91精品国产91久久久久久不卞 | 国产精品久久久久久238 | 欧美精品欧美极品欧美激情 | 国产精品视频海角社区88 | 男女做性免费网站 | 一级做a在线观看 | 羞羞视频免费观看网站 | 91国在线高清视频 | 全免费午夜一级毛片真人 | 免费播放欧美毛片 | 亚洲第一成人在线视频 | 国产精品视频一区二区三区四区国 | 欧美女优一区 | 欧美在线观看视频网站 | 久久亚洲精品久久国产一区二区 | 在线视频观看成人 | 青青操国产 | 日韩美香港a一级毛片 | 精品在线视频播放 | 中文字幕一区在线观看视频 | 国产精品久久久久久久av | 亚洲一二区视频 | 久久久久久久一区二区三区 | 国产成年人小视频 | 色阁阁69婷婷 |