APACHE 重寫規(guī)則(mod_rewrite)

看了一些關(guān)于.htaccess,apache重寫url的規(guī)則近弟,一般都寫得很清楚。但是對(duì)于我一個(gè)小白挺智,感覺(jué)要挖的東西挺多的祷愉,并不能滿足我的需求。于是就追著apache的文檔中的mod_rewrite查看,講得很清楚二鳄。
當(dāng)然赴涵,除了在.htaccess中配置相關(guān)的重寫規(guī)則,也可以在apache的httpd.conf或者虛擬主機(jī)配置httpd-vhosts.conf中配置订讼,參考官方例子如下:

邊截圖邊解釋一下髓窜,基于我自己的英文翻譯和理解,如有不同之處請(qǐng)按照你們自己的理解躯嫉。

1. apache mod_rewrite 模塊介紹

對(duì)于重寫模塊纱烘,相信都不陌生,一般的web項(xiàng)目都會(huì)用到url重定向祈餐,這就需要使用mod_rewrite的模塊擂啥,在.htaccess文件來(lái)完成。
首先帆阳,開啟apache的mod_rewrite的模塊哺壶,注釋httpd.conf中的下列文字即可開啟。
LoadModule rewrite_module modules/mod_rewrite.so

官方文檔介紹:


image.png
2.正則表達(dá)式

mod_rewrite使用的是Perl Compatible Regular Expression的詞匯蜒谤,這里講解簡(jiǎn)單的正則表達(dá)式幫助理解山宾,詳細(xì)的正則表達(dá)式移至http://perldoc.perl.org/perlre.htmlhttp://shop.oreilly.com/product/9780596528126.do

1)需要的最小正則表達(dá)式

需要的最小正則表達(dá)式鳍徽,中文自行搜索比較即可

mod_rewrite中經(jīng)常會(huì)使用到 ! 字符资锰,一般用在正則表達(dá)式前表示否定。

2)官方給出一個(gè)簡(jiǎn)單的重寫url的公式例子阶祭,比較容易理解绷杜,就不翻譯了。

image.png

3 ) RewriteCond
RewriteCond指令定義一個(gè)規(guī)則條件濒募。一個(gè)或多個(gè)RewriteCond可以在一個(gè)RewriteRule指令之前鞭盟。只有當(dāng)URI的當(dāng)前狀態(tài)與其模式相匹配時(shí)才會(huì)使用下面的規(guī)則,并且如果滿足這些條件的話瑰剃。

TestString是一個(gè)字符串齿诉,除了純文件以外,它還可以包含以下擴(kuò)展結(jié)構(gòu):

  • RewriteRule反向引用:這些是形式$N(0 <= N <= 9)的反向引用晌姚。$1到$9提供對(duì)正則分組部分(括號(hào))的訪問(wèn)粤剧。從屬于RewriteRule就是當(dāng)前的RewriteCond條件設(shè)置。$0提供了與該模式匹配的整個(gè)字符串的訪問(wèn)權(quán)挥唠。
  • RewriteCond反向引用:這些是由%N(0 <= N <= 9)組成的反向引用俊扳。%1到%9提供對(duì)正則的分組部分的訪問(wèn)(在括號(hào)中),從當(dāng)前條件集的最后匹配RewriteCond猛遍。$0提供對(duì)整個(gè)字符串的訪問(wèn),該字符串與該模式匹配。
  • RewriteMap擴(kuò)展:這些由樣式 ${mapname:key|default} 組成的擴(kuò)展懊烤。
  • 服務(wù)器變量:這些變量是由樣式 %{NAME_OF_VARIALBE}組成的梯醒,NAME_OF_VARIABLE可以是如下例表中的字符串:

    這些變量都對(duì)應(yīng)相似的命名HTTP MIME-headers,APACHE HTTP服務(wù)器的C 變量腌紧,或者Unix系統(tǒng)中的tm結(jié)構(gòu)體茸习。大多數(shù)文檔在手冊(cè)或CGI規(guī)范的其他地方被記錄。
    SERVER_NAME和SERVER_PORT分別依賴于UseCanonicalName和UseCanonicalPhysicalPort壁肋。
    那些對(duì)于 mod_rewrite很特別的部分包括下面這些 :

其他應(yīng)該注意的:

    1. 變量SCRIPT_FILENAME和REQUEST_FILENAME包含相同的值——Apache HTTP服務(wù)器內(nèi)部REQUEST_REC結(jié)構(gòu)的文件名字段的值号胚。第一個(gè)名稱是眾所周知的CGI變量名,而第二個(gè)名稱是REQUEST_URI的相應(yīng)對(duì)應(yīng)物(它包含request_rec的uri字段的值)浸遗。
      如果發(fā)生了替換猫胁,并且重寫繼續(xù),那么兩個(gè)變量的值將相應(yīng)地更新跛锌。
      如果在每個(gè)服務(wù)器環(huán)境中使用(例如在請(qǐng)求被映射到文件系統(tǒng)之前)弃秆,SCRIPT_FILENAME和REQUEST_FILENAME不能包含完整的本地文件系統(tǒng)路徑,因?yàn)樵谔幚淼倪@個(gè)階段路徑未知髓帽。在這種情況下菠赚,兩個(gè)變量都將包含REQUEST_URI的值。為了在每個(gè)服務(wù)器上下文中獲得請(qǐng)求的完整的本地文件系統(tǒng)路徑郑藏,可以使用基于url的查詢指令%{LA-U:REQUEST_FILENAME}來(lái)確定REQUEST_FILENAME的最終值衡查。
    1. %{ENV:variable} 中variable可以是任何環(huán)境變量,都是可以使用的必盖。這是通過(guò)Apache httpd服務(wù)器進(jìn)程的 getenv() 拌牲,如果沒(méi)有找到話,就從 Apache httpd結(jié)構(gòu)進(jìn)行查找筑悴。
    1. %{SSL:variable} 中variable的名字是一個(gè)SSL環(huán)境變量的名稱们拙,不管mod_ssl是否加載都可以使用。但是如果沒(méi)有加載mod_ssl的話阁吝,會(huì)擴(kuò)展為空字符串砚婆。例如: %{SSL:SSL_CIPHER_USEKEYSIZE}可能擴(kuò)展到128。
    1. %{HTTP:header},header 可以是任何一個(gè)HTTP MIME-header的名稱突勇,總是可以用來(lái)獲取HTTP請(qǐng)求中發(fā)送的關(guān)部信息装盯。例:%{HTTP:Proxy-Connection}是HTTP頭部信息中{Proxy-Connection}的值 。如果在一個(gè)條件 中使用了HTTP頭甲馋,當(dāng)請(qǐng)求的條件評(píng)估為真時(shí)埂奈,這個(gè)頭部信息將被添加到響應(yīng)的變化頭部信息中。如果請(qǐng)求條件評(píng)估為假時(shí)定躏,則不添加账磺。對(duì)于適應(yīng)的調(diào)整緩存芹敌,需要將HTTP頭添加到響應(yīng)的不同頭部中。
      必須記住垮抗,在'ornext|OR'的標(biāo)志情況下氏捞,條件會(huì)遵循一個(gè)短路邏輯,這樣就不會(huì)對(duì)某些條件進(jìn)行評(píng)估冒版。
    1. %{LA-U:variable}可用于執(zhí)行一個(gè)內(nèi)部(URL-based)的子請(qǐng)求液茎,以確定變量的最終值。這可以用來(lái)訪問(wèn)重寫的變量辞嗡,而這在當(dāng)前階段是不可用的捆等,但是將在后面的階段中設(shè)置。
      例如续室,要根據(jù)每個(gè)服務(wù)器上下文中REMOTE_USER變量(httpd.conf 文件)重寫栋烤,你必須使用 %{LA-U:REMOTE_USER}- 這個(gè)變量由認(rèn)證階段設(shè)置,該階段是在URL轉(zhuǎn)換階段之后(在mod_rewrite操作期間)猎贴。
      另一方面班缎,因?yàn)閙od_rewrite實(shí)現(xiàn)了它的每個(gè)目錄上下文(.htaccess文件)通過(guò)API的Fixup階段,由于認(rèn)證階段在此階段 之前她渴,您可以在該上下文中使用%{REMOTE_USER}达址。***
    1. %{LA-F:variable} 可用于執(zhí)行內(nèi)部的子請(qǐng)求(基于文件名),以確定變量的最終值趁耗。大多數(shù)時(shí)候沉唠,這和上面的LA-U是一樣的。

CondPattern是條件模式苛败,它是一個(gè)正則表達(dá)式满葛,應(yīng)用于TestString的當(dāng)前實(shí)例。在匹配CondPattern之前罢屈,先對(duì)TestString進(jìn)行評(píng)估嘀韧。
CondPattern通常是一個(gè)perl兼容的正則表達(dá)式,但是還有一些附加語(yǔ)法可以用來(lái)對(duì)TestString執(zhí)行其他有用的測(cè)試:

    1. 你可以在模式字符串之前加上 '!' 字符( 感嘆號(hào) ) 來(lái)指定一個(gè)不匹配的模式缠捌。
    1. 你可以執(zhí)行詞法字符串比較:
      '<CondPattern'(詞法之前)
      把CondPattern當(dāng)作普通字符串锄贷,并將它與TestString進(jìn)行比較。如果在CondPattern之前曼月,TestString是正確的谊却。
      '>CondPattern' (詞法之后)
      把CondPattern當(dāng)作普通字符串,并將它與TestString進(jìn)行比較哑芹。如果在CondPattern之后炎辨,TestString是正確的。
      '=CondPattern'(等于詞法)
      把CondPattern當(dāng)作普通字符串聪姿,并將它與TestString進(jìn)行比較碴萧。如果TestString等于CondPattern就是正確的乙嘀。(兩個(gè)字符串必須絕對(duì)相等,字符是字符)破喻。如果CondPattern是“”(兩個(gè)引號(hào))這將比作TestString為空字符串乒躺。
      '<=CondPattern(小于或等于詞法)'
      把CondPattern當(dāng)作普通字符串,并將它與TestString進(jìn)行比較低缩。如果TestString在詞法之前或者等于詞法就是真。(兩個(gè)字符串必須絕對(duì)相等曹货,字符是字符)咆繁。
      '>=CondPattern(大于或等于詞法)'
      把CondPattern當(dāng)作普通字符串,并將它與TestString進(jìn)行比較顶籽。如果TestString在詞法之后或者等于詞法就為真玩般。(兩個(gè)字符串必須絕對(duì)相等,字符是字符)礼饱。
    1. 你可以執(zhí)行整數(shù)比較:
      '-eq' (數(shù)值相等):
      TestString當(dāng)作一個(gè)整數(shù)坏为,并且與CondPattern進(jìn)行數(shù)值比較。兩個(gè)數(shù)值相等就為真镊绪。
      '-ge' (數(shù)值大于或等于):
      TestString當(dāng)作一個(gè)整數(shù)匀伏,并且與CondPattern進(jìn)行數(shù)值比較。TestString數(shù)值上大于或等于CondPattern就為真蝴韭。
      '-gt'(數(shù)值大于):
      TestString當(dāng)作一個(gè)整數(shù)够颠,并且與CondPattern進(jìn)行數(shù)值比較。它的數(shù)值大于CondPattern那就為真榄鉴。
      '-le'(數(shù)值小于或等于):
      TestString當(dāng)作一個(gè)整數(shù)履磨,并且與CondPattern進(jìn)行數(shù)值比較。它的數(shù)值小于或CondPattern就為真庆尘。使用-L或者-h 變量避免與 -l混淆剃诅。
      '-lt'(數(shù)值小于):
      TestString當(dāng)作一個(gè)整數(shù),并且與CondPattern進(jìn)行數(shù)值比較驶忌。它的數(shù)值小于CondPattern就為真矛辕。使用-L或者-h 變量避免與 -l混淆。***
    1. 你可以執(zhí)行各種文件屬性測(cè)試:
      '-d'(是目錄)
      TestString當(dāng)作一個(gè)路徑名稱位岔,測(cè)試它是否存在且是一個(gè)路徑如筛。
      '-f'(是一個(gè)普通文件)
      TestString當(dāng)作一個(gè)路徑名稱,測(cè)試它是否存在且是一個(gè)普通文件抒抬。
      '-F'(是通過(guò)子請(qǐng)求的現(xiàn)有文件)
      檢查TestString是否是有效的文件杨刨,通過(guò)所有服務(wù)器的當(dāng)前配置的訪問(wèn)控制來(lái)訪問(wèn)該路徑。這將使用內(nèi)部 子請(qǐng)求來(lái)執(zhí)行檢查擦剑,所以要小心使用它---它會(huì)影響服務(wù)器性能妖胀。
      '-H'(是符號(hào)鏈接芥颈,bash約定)
      詳見 -I
      '-I'(是符號(hào)鏈接)
      TestString當(dāng)作一個(gè)路徑名稱,測(cè)試它是否存在且為一個(gè)符號(hào)鏈接赚抡。當(dāng)使用lt或-le測(cè)試時(shí)如果可能出現(xiàn)混淆爬坑,也可使用-L或者-h的bash約定。
      '-L'(是符號(hào)鏈接涂臣,bash約定)
      詳見-I
      '-s'(是普通文件盾计,有大小)
      TestString被當(dāng)作一個(gè)路徑名稱,測(cè)試它是否存在且一個(gè)文件大小于0的常規(guī)文件赁遗。
      '-U'(是通過(guò)子請(qǐng)求署辉,存在的URL)
      檢查TestString是否是一個(gè)有效的URL,通過(guò)所有服務(wù)器的當(dāng)前配置的訪問(wèn)控制來(lái)訪問(wèn)該路徑岩四。這將使用內(nèi)部子請(qǐng)求來(lái)執(zhí)行檢查哭尝,所以要小心使用它---它會(huì)影響服務(wù)器的性能。
      '-x'(有可執(zhí)行的權(quán)限)
      TestString當(dāng)作一個(gè)路徑名稱剖煌,測(cè)試它是否存在且有可執(zhí)行的權(quán)限材鹦。這些權(quán)限是根據(jù)底層操作系統(tǒng)來(lái)確定的。
      注意:所有這些測(cè)試也可用一個(gè)感嘆號(hào)(8ⅰ)來(lái)否定它們的含義桶唐。
    1. 如果TestString有一些特殊的表達(dá)式,CondPattern將把它們看作一個(gè)ap_expr.
      在如下的例子中箩做,-strmatch用于比較REFERER和站點(diǎn)主機(jī)名莽红,以阻止不必要的熱鏈接。
      RewriteCond expr "! %{HTTP_REFERER} -strmatch '://%{HTTP_HOST}/' "
      RewriteRule ^/images - [F]
    1. 也可為CondPattern后設(shè)置特殊的標(biāo)志邦邦,[flags]作為RewriteCond指令的第三個(gè)參數(shù)安吁,其中的標(biāo)志是一個(gè)以逗號(hào)分隔的下列任何標(biāo)記的列表:
      'nocase|NC'(no case):
      這使得測(cè)試不區(qū)分大小寫——“A-Z” 和 “a-z”之間的區(qū)別被忽略了,無(wú)論是在擴(kuò)展的TestString還是CondPattern中燃辖。該標(biāo)記僅有效于TestString和CondPattern鬼店。它對(duì)文件系統(tǒng)和子請(qǐng)求檢查沒(méi)有影響。
      'ornext|OR'(or next condition)
      用這個(gè)來(lái)將規(guī)則條件與局部或隱式結(jié)合起來(lái)黔龟。典型的例子:
      RewriteCond %{REMOTE_HOST} ^host1 [OR]
      RewriteCond %{REMOTE_HOST} ^host2 [OR]
      RewriteCond %{REMOTE_HOST} ^host3
      RewriteRule ...some special stuff for any of these hosts...
      沒(méi)有這個(gè)標(biāo)識(shí)妇智,你需要寫三遍condition/rule對(duì)。
      'novary|NV'(沒(méi)有變化)
      如果一個(gè)HTTP頭部在條件中使用氏身,這個(gè)標(biāo)識(shí)阻止在回應(yīng)的變化頭部中添加這個(gè)頭部信息巍棱。
      如果響應(yīng)的表示因該頭部信息的值而變化,那么使用此標(biāo)志可能會(huì)破壞響應(yīng)的適當(dāng)緩存蛋欣。因此航徙,只有在理解了變化頭的含義時(shí),才應(yīng)用使用這個(gè)標(biāo)志陷虎。
      Example:
      為了根據(jù)"User-Agent:"請(qǐng)求的頭到踏,重寫網(wǎng)站主頁(yè)杠袱,可以使用如下:
      RewriteCond %{HTTP_USER_AGENT} ^Mozilla
      RewriteRule ^/$ /homepage.max.html [L]

      RewriteCond %{HTTP_USER_AGENT} ^Lynx
      RewriteRule ^/$ /homepage.min.html [L]

      RewriteRule ^/$ /homepage.std.html [L]
      解釋:如果你使用一個(gè)它定義為'Mozilla'的瀏覽器(包括 Netscape Navigator,Mozilla etc),你將取得最大的主頁(yè)(有可能會(huì)包括框架,或者其他特殊特性)窝稿。如果你使用Lynx瀏覽器(這是基于終端)楣富,你將取得最小的主頁(yè)(有可能是一個(gè)專為輕變,只顯示文本的瀏覽器設(shè)計(jì)的版本)伴榔。如果既不是上面條件中適用的瀏覽器(你使用任何瀏覽器纹蝴,或者你的瀏覽器定義它自己為不標(biāo)準(zhǔn)版的),你將取得std(標(biāo)準(zhǔn))的主頁(yè)踪少。

4) 重寫規(guī)則由三個(gè)部分組成
-> 樣式(pattern): 請(qǐng)求的url要滿足此正則表達(dá)式;
-> 替換(substitution): 滿足正則表達(dá)式的請(qǐng)求url被重寫的路徑;
-> [flags] : 影響重寫請(qǐng)求的選項(xiàng);


舉例:
A. 系統(tǒng)文件路徑轉(zhuǎn)移至另一個(gè)路徑
RewriteRule ^/games /usr/local/games/web
這有點(diǎn)像別名設(shè)置骗灶。如訪問(wèn)/games/xxx.jpg會(huì)直接指向/usr/local/games/web/xxx.jpg路徑。
B. 網(wǎng)絡(luò)路徑到資源
RewriteRule ^/foo$ /bar
如果文件根目錄設(shè)置為 /usr/local/apache2/htdocs秉馏,那么它將映射http://example.com/foo 的請(qǐng)求到 路徑 /usr/local/apache2/htdocs/bar。
C. 完整的url重寫
RewriteRule ^/product/view$ http://site2.example.com/seeproduct.html [R]
這將引導(dǎo)用戶生成一個(gè)新的請(qǐng)求到具體的URL脱羡。
替換也可以包含請(qǐng)求中正則表達(dá)式匹配的部分追加至其后
RewriteRule ^/product/(.*)/view$ /var/web/productdb/$1
變量$1將被樣式中的圓括號(hào)中的正則表達(dá)式匹配部分替換
舉個(gè)例子:
請(qǐng)求為http://example.com/product/r14df/view萝究,將映射至路徑 /var/web/productdb/r14df。


3. RewriteRule Flags(重寫規(guī)則中的[flags])

apache的重寫規(guī)則可以被一個(gè)或者多個(gè)標(biāo)識(shí)(flags)修改锉罐。標(biāo)識(shí)包含在規(guī)則最后的方括號(hào)中帆竹,多個(gè)標(biāo)識(shí)用逗號(hào)>隔開。
RewriteRule pattern target [Flag1,Flag2,Flag3]
所有的標(biāo)識(shí)有短的術(shù)語(yǔ)脓规,也有長(zhǎng)的術(shù)語(yǔ)(極少部分的除外)栽连,如長(zhǎng)術(shù)語(yǔ)cookie,短的術(shù)語(yǔ)就是co。flags不區(qū)分大小寫侨舆。
挑幾個(gè)例子說(shuō)吧秒紧,其他更多請(qǐng)參照官方文檔。
B(跳過(guò)回溯引用 escape backreferences)
[B]標(biāo)識(shí)指令重寫規(guī)則在應(yīng)用轉(zhuǎn)換之前跳過(guò)非字母數(shù)字字符挨下。
mod_rewrite在映射url之前不會(huì)跳過(guò)它們熔恢,所以回溯引用在他們被使用的同時(shí)也不會(huì)被跳過(guò)。使用B標(biāo)識(shí)臭笆,在回溯引用中非字母數(shù)字字符會(huì)被跳過(guò)叙淌。舉例:
RewriteRule ^search/(.*)/$ /search.php?term=$1
搜索表達(dá)式'x & y/z',瀏覽器會(huì)加密它成為'x%20%26%20y%2Fz'愁铺,請(qǐng)求就成為了search/x%20%26%20y%2Fz鹰霍。沒(méi)有B標(biāo)識(shí),重寫規(guī)則會(huì)映射成為一個(gè)無(wú)效的URL‘search.php?term=x & y/z’茵乱,于是會(huì)被加密成search.php?term=x%20&y%2Fz=茂洒,當(dāng)然這并不是所期望的那樣。

如果在其后面加上[B]標(biāo)識(shí)似将,參數(shù)會(huì)在傳給輸入的URL前再次加密获黔。結(jié)果就是一個(gè)正確的映射 /search.php?term=x%20%26%20y%2Fz蚀苛。
**注意:你同時(shí)需要設(shè)置AllowEncodeSlashes為On,這樣才能讓這種特殊情況正常工作玷氏,httpd不允許加密URLs中的斜杠堵未,如果碰見了就會(huì)返回404。


F 禁止
使用[F]標(biāo)識(shí)導(dǎo)致服務(wù)器返回403禁止?fàn)顟B(tài)碼給客戶端盏触。直接使用Deny也能完成這樣的效果渗蟹,但是[F]在返回禁止?fàn)顟B(tài)時(shí)更加靈活。
接下來(lái)的規(guī)則會(huì)禁止執(zhí)行.exe文件從你的服務(wù)器中導(dǎo)出赞辩。
RewriteRule .exe - [F]
例子中使用"-"語(yǔ)法作為重寫的目標(biāo)雌芽,意思就是請(qǐng)求的URI沒(méi)有被修改。如果你要禁止此請(qǐng)求辨嗽,沒(méi)有理由重寫成其他的URI世落。
當(dāng)使用[F]時(shí),[L]也隱藏使用了。這就是,回應(yīng)立即返回踢匣,并不會(huì)使用進(jìn)一步的規(guī)則充择。


L最后的
[L]標(biāo)識(shí)促使mod_rewrite阻止繼續(xù)執(zhí)行規(guī)則制定。在大多數(shù)的內(nèi)容中,它意味著如果這個(gè)規(guī)則匹配,沒(méi)有進(jìn)一步的規(guī)則會(huì)執(zhí)行。這跟Perl中的last命令或者C中的break命令是一致的体箕。使用這個(gè)標(biāo)識(shí)表明當(dāng)前的規(guī)則應(yīng)該立即執(zhí)行且無(wú)需考慮進(jìn)一步的規(guī)則。

在這里舉的例子挑童,會(huì)重寫任何請(qǐng)求到index.php累铅,最初的請(qǐng)求作為一個(gè)請(qǐng)求字符串參數(shù)添加到index.php中。
但是站叼,RewriteCond確保當(dāng)請(qǐng)求已經(jīng)給到index.php時(shí)争群,RewriteRule會(huì)被跳過(guò)。
RewriteBase /
RewriteCond %{REQUEST_URI} != /index.php
RewriteRule ^(.*) /index.php?req=$1 [L,PT]


PT轉(zhuǎn)移

4. 一些access例子(這些例子不一定有作用大年,理解這些規(guī)則更重要)
  • 1)禁止圖片熱鏈接
    描述:
    下面的技術(shù)禁止在頁(yè)面中插入其他站點(diǎn)换薄,包括你的圖像。這種做法通常被稱為“熱鏈接”翔试,并導(dǎo)致你的帶寬被用于其他人的站點(diǎn)提供內(nèi)容轻要。
    解決:
    這個(gè)技術(shù)依賴于變量HTTP_REFERER的值,這是可選的垦缅。因此冲泥,有些人有可能繞開這一限制。但是,大多數(shù)用戶將體驗(yàn)到失敗的請(qǐng)求凡恍,隨著時(shí)間的推移志秃,這將導(dǎo)致圖片從其他站點(diǎn)中刪除。
    有很多方面可以解決這個(gè)情況嚼酝。
    在第一個(gè)例子中浮还,如果它沒(méi)有從我們網(wǎng)站上的一個(gè)頁(yè)面發(fā)起請(qǐng)求,那我們只是拒絕請(qǐng)求闽巩。為了本例的目的钧舌,我們假設(shè)我們網(wǎng)站是 www.example.com
    RewriteCond %{HTTP_REFERER} !^$
    RewriteCond %{HTTP_REFERER} !www.example.com [NC]
    RewriteRule .(gif|jpg|png)$ - [F,NC]
    在第二個(gè)例子中,我們顯示另一個(gè)鏡像替代失敗請(qǐng)求
    RewriteCond %{HTTP_REFERER} !^$
    RewriteCond %{HTTP_REFERER} !www.example.com [NC]
    RewriteRule .(gif|jpg|png)$ /images/go-away.png [R,NC]
    在第三個(gè)例子中涎跨,我們直接跳轉(zhuǎn)請(qǐng)求到當(dāng)前圖片所在的其他網(wǎng)站
    RewriteCond %{HTTP_REFERER} !^$
    RewriteCond %{HTTP_REFERER} !www.example.com [NC]
    RewriteRule .(gif|jpg|png)$ http://other.example.com/image.gif [R,NC]
    在這些技術(shù)中洼冻,最后兩種方法最有效地讓人們停止熱鏈接你的圖片,因?yàn)樗麄儾粫?huì)看到他們期望看到的
    圖像隅很。
    討論:
    如果你想要做的就是拒絕訪問(wèn)資源撞牢,而不是將請(qǐng)求重定向到其他地方,那么可以在不使用mod_rewrite的情況下完成此任務(wù):
    SetEnvIf Referer example .com localreferer
    <FilesMatch .(jpg|png|gif)$>
    Require env localreferer
    </FilesMatch>
  • 2) 拒絕黑名單中的主機(jī)
    RewriteEngine on
    RewriteMap hosts-deny txt:/path/to/hosts.deny
    RewriteCond ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND} !=NOT-FOUND [OR]
    RewriteCond ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND} !=NOT-FOUND
    RewriteRule ^ - [F]

hosts.deny
注意叔营!這是一個(gè)映射普泡,不是一個(gè)名單,即使我們就是這樣希望它的审编。
mod_rewrite 解析它作為 鍵/值 對(duì),所以至少每個(gè)條目必須有虛擬的值"-"歧匈。

193.102.180.41 -
bsdtil.sdm.de -
192.76.162.40 -

  • 3) 基于referer的引流
    描述:
    根據(jù)請(qǐng)求的Referer重定向請(qǐng)求垒酬,每個(gè)referer的目標(biāo)不同。
    解決:
    RewriteMap deflector txt:/path/to/deflector.map

    RewriteCond %{HTTP_REFERER} !=""
    RewriteCond ${deflector:%{HTTP_REFERER} } =-
    RewriteRule ^ %{HTTP_REFERER} [R,L]

    RewriteCond %{HTTP_REFERER} != ""
    RewriteCond ${deflector:%{HTTP_REFERER}|NOT-FOUND} !=NOT-FOUND
    RewriteRule ^ ${deflector:%{HTTP_REFERER}} [R,L]

注意:map文件列出了每個(gè)referer的重定向目標(biāo)件炉,或者勘究,如果我們只是希望重定向到它們來(lái)自哪里,那么“-”就需要放在map里斟冕。
deflector.map
http://badguys.example.com/bad/index.html -
http://badguys.example.com/bad/index2.html -
http://badguys.example.com/bad/index3.html http://somewhere.example.com

  • 4) mod_rewrtite重定向和重映射
    從舊到新(內(nèi)部)
    描述:
    假設(shè)我們最近重新命名了頁(yè)面foo.html為bar.html口糕,現(xiàn)在想向后兼容舊的URL。但是景描,我們想使用舊URL的用戶不會(huì)察覺(jué)這些頁(yè)面被重命名秀撇。那么,我們不想更改他們?yōu)g覽器中的地址呵燕。
    解決:
    RewriteEngine on
    RewriteRule ^/old.html$ /new.html [PT]
    重寫舊到新(外部)
    描述:
    再次假設(shè)我們最近重命名foo.html為bar.html棠绘,現(xiàn)在想向后說(shuō)兼容舊的URL。但是這次我們想將用戶的舊URL得到新的地址的提示氧苍,例,他們的瀏覽器地址欄也應(yīng)該改變让虐。
    解決:
    RewriteEngine on
    RewriteRule ^/foo.html$ bar.html [R]
    資源移至其他的服務(wù)器
    描述:
    如果一項(xiàng)資源已經(jīng)移至其他的服務(wù)器紊撕,當(dāng)用戶更新他們的書簽的時(shí)候,你可能希望舊服務(wù)器上的URLs繼續(xù)運(yùn)行一斷時(shí)間逛揩。
    解決:
    你可以用mod_rewrite跳轉(zhuǎn)到這些URLs到新的服務(wù)器上麸俘,但是你也許也考慮到使用Redirect或者RedirectMatch指令从媚。
    ``#With mod_rewrite
    RewriteEngine on
    RewriteRule ^/docs/(.+) http://new.example.com/docs/$1 [R,L]

    ``#With RedirectMatch
    RedirectMatch ^/docs/(.*) http://new.example.com/docs/$1

    ``#With Redirect
    Redirect /docs/ http://new.example.com/docs/
    從靜態(tài)到動(dòng)態(tài)
    描述:
    如何用一種無(wú)縫的方式轉(zhuǎn)換靜態(tài)頁(yè)面foo.html到動(dòng)態(tài)變量 foo.cgi,例喷众,沒(méi)有瀏覽器或用戶注意到紧憾。
    解決:
    我們只需要將URL重寫為CGI-script,并強(qiáng)制處理程序成為CGI-script憔四,以便將其作為CGI程序執(zhí)行般眉。這是對(duì)/quux/foo.html的請(qǐng)求內(nèi)部對(duì)/quux/foo.cgi的調(diào)用甸赃。
    RewriteEngine on
    RewriteBase /~quux/
    RewriteRule ^foo.html$ foo.cgi [H=cgi-script]
    文件擴(kuò)展的向后兼容性
    描述:
    在合并document.YYYY到document.XXXX時(shí),我們?cè)撊绾巫龅経RLs向后兼容(依然存在虛擬的)络断?例项玛,在傳輸完一堆.html文件到.php?
    解決:
    我們將名稱改寫為basename稍计,并測(cè)試新的擴(kuò)展存在。如果它存在净刮,我們就取那個(gè)名字剥哑,否則我們重寫URL到它的初始狀態(tài)淹父。

    backward compatibility ruleset for rewriting document.html to document.php
    when and only when document.php exists

    <Direcotry /var/www/htdocs>
    RewriteEngine on
    RewriteBase /var/www/htdocs
    RewriteCond $1.php -f
    RewriteCond $1.html !-f
    RewriteRule ^(.*).html$ $1.php
    </Directory>
    討論:
    這個(gè)例子使用了一個(gè)經(jīng)常被忽略的mod重寫特性暑认,它利用了規(guī)則集的執(zhí)行順序。特別是座哩,mod重寫在對(duì)rewriterecond指令進(jìn)行評(píng)估之前粮彤,對(duì)其左邊的部分進(jìn)行評(píng)估导坟。因此,$1已經(jīng)RewriteCond指令被評(píng)估的時(shí)候被定義尘惧。這允許我們使用相同的基本文件名來(lái)測(cè)試原始文件(document.html)和target(document.php)文件的存在递递。
    該規(guī)則集被設(shè)計(jì)為在每個(gè)目錄上下文中使用(在一個(gè)目錄中或在.htaccess文件中)漾狼,以便-f檢查查找正確的目錄路徑饥臂。您可能需要設(shè)置一個(gè)RewriteBase指令來(lái)指定您正在工作的目錄基礎(chǔ)隅熙。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市酵熙,隨后出現(xiàn)的幾起案子驰坊,更是在濱河造成了極大的恐慌,老刑警劉巖察藐,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件分飞,死亡現(xiàn)場(chǎng)離奇詭異譬猫,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)别洪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門蕉拢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)诚亚,“玉大人,你說(shuō)我怎么就攤上這事闸准∩颐穑” “怎么了敏释?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵钥顽,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我闽铐,道長(zhǎng)奶浦,這世上最難降的妖魔是什么澳叉? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任沐悦,我火速辦了婚禮所踊,結(jié)果婚禮上概荷,老公的妹妹穿的比我還像新娘。我一直安慰自己继薛,他們只是感情好遏考,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布蓝谨。 她就那樣靜靜地躺著譬巫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪诱贿。 梳的紋絲不亂的頭發(fā)上咕缎,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天凭豪,我揣著相機(jī)與錄音,去河邊找鬼孔厉。 笑死末早,一個(gè)胖子當(dāng)著我的面吹牛然磷,可吹牛的內(nèi)容都是我干的刊驴。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼梭纹,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼致份!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起氮块,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤滔蝉,失蹤者是張志新(化名)和其女友劉穎蝠引,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體矫夯,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡茧痒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年旺订,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了超燃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡樱调,死狀恐怖笆凌,靈堂內(nèi)的尸體忽然破棺而出士葫,到底是詐尸還是另有隱情慢显,我是刑警寧澤欠啤,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布洁段,位于F島的核電站共郭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏纽疟。R本人自食惡果不足惜污朽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一龙考、第九天 我趴在偏房一處隱蔽的房頂上張望晦款。 院中可真熱鬧,春花似錦蛇损、人聲如沸坛怪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)祭务。三九已至怪嫌,卻和暖如春岩灭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背贰拿。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工膨更, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缴允,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓矗漾,卻偏偏與公主長(zhǎng)得像敞贡,于是被迫代替她去往敵國(guó)和親摄职。 傳聞我的和親對(duì)象是個(gè)殘疾皇子谷市,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 重寫規(guī)則 【重寫規(guī)則的作用范圍】 可以使用在Apache主配置文件httpd.conf中 可以使用在httpd.c...
    桖辶殤閱讀 1,659評(píng)論 0 0
  • 前兩天部署一個(gè)項(xiàng)目到本機(jī)環(huán)境迫悠,從nginx轉(zhuǎn)到apache创泄,因?yàn)椴皇煜pache的重寫規(guī)則,給自己挖了很多坑板驳。碍拆。...
    牽小馬過(guò)河閱讀 1,034評(píng)論 0 0
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理感混,服務(wù)發(fā)現(xiàn),斷路器婆跑,智...
    卡卡羅2017閱讀 134,600評(píng)論 18 139
  • nginx重寫規(guī)則 nginx rewrite 正則表達(dá)式匹配 大小寫匹配 ~ 為區(qū)分大小寫匹配 ~* 為不區(qū)分大...
    桖辶殤閱讀 5,533評(píng)論 0 2
  • 對(duì)于巴菲特的投資理念滑进,大多數(shù)人都比較熟悉扶关。但我們?yōu)槭裁醇热恢溃瑓s還是沒(méi)有巴菲特那樣的投資收益呢搀庶?其實(shí)铜异,我覺(jué)得最關(guān)...
    鹿鹿無(wú)畏閱讀 610評(píng)論 0 51