僞靜態與重定向--RewriteRule解釋的比較清楚

環境:windows 10,phpstudy,sublime text。服務器使用Apache,網站根目錄爲E:\phpstudy\www\,所以.htaccess放在www目錄下。

RewriteRule語法說明:

RewriteRule  模式匹配  替換的URL  [flags]

模式匹配使用perl語言的正則表達式語法,同時還可以使用一些rewrite預定義的變量

替換的URL支持模式匹配的結果和rewrite變量

多個flag用逗號隔開

例子1

此時根目錄只有index.htm,將所有訪問 *.htm的請求都重定向到  *.html

1

2

3

RewriteEngine On

RewriteRule ^(.*)\.htm$ $1.html

# $1在正則表達式中表示前面第一個匹配的子表達式,即.*部分 

  注意配置中的RewriteEngine On表示開啓重寫,注意請求的URL是 index.htm ,重定向到index.html,但是地址欄仍然爲index.htm

 如果在根目錄創建一個index.html文件,再刷新的話,結果就不同了:

 

RewriteRule R flag說明

R表示強制外部重定向,後面可以加301(永久重定向)或者302(暫時重定向)跳轉,不加默認302(暫時重定向),加了R flag之後,地址欄的URL會改變

這兩種重定向的區別在於:SEO搜索引擎對網站是有評分的,如果使用臨時重定向,則不會將搜索引擎對以前URL的評分 給 臨時重定向(新的)的網站URL,會爲新的URL產生一個新的評分;而永久重定向則會將評分轉給新的URL。

使用示例:

  此時根目錄爲空,仍舊訪問localhost/index.htm

1

2

3

4

RewriteEngine On

RewriteRule ^(.*)\.htm$ $1.html [R]

#等價於下面這一條

#RewriteRule ^(.*)\.htm$ $1.html [R=302]

注意上面的圖片中,外部重定向時,地址欄的URL發生了改變,並且是按照磁盤的路徑去查找,而不是按照網站根目錄去查找,這時可以在$1前面加一個斜線 / ,表示重定向的基地址爲網站根目錄,如下例:

1

2

3

4

RewriteEngine On

RewriteRule ^(.*)\.htm$ /$1.html [R]

#等價於下面這一條

#RewriteRule ^(.*)\.htm$ /$1.html [R=302]

創建index.html文件,再訪問localhost/index.htm

 

 

RewriteRule C flag說明

C表示鏈接下一規則,如果在一條規則後面加了該flag後,這條規則就和下一條規則成爲一個整體,如果這一條規則不匹配,那麼下一條也不進行匹配,類似於“拉着別人下水的”的情景。

注意這裏的匹配的時候,前一條的匹配之後,URL改變了,然後,將新的URL進行下一條規則的匹配。

實例:

  網站根目錄下只有index.html和index.php文件,

1

2

3

RewriteEngine On

RewriteRule ^(.*)\.htm$     /$1.html [C]

RewriteRule ^(.*)\.html$    /$1.php

  現在結果如下圖:

而如果直接訪問index.html,那麼因爲不匹配第一條規則,所以不進行第二條規則匹配,不會重定向到index.php,會直接輸出index.html的內容。

 

RewriteRule L flag說明

如果一條規則的後面添加了這個L flag,那麼如果這條規則匹配,就不在進行下一條規則的匹配,如果改規則不匹配,則會繼續進行下一規則的匹配。

實例:

  根目錄下有index.html,index.php,訪問index.htm,因爲匹配到了第一條規則,並且後面有L flag,所以不會匹配下面一條

1

2

3

RewriteEngine On

RewriteRule ^(.*)\.htm$     /$1.html [L]

RewriteRule ^(.*)\.html$    /$1.php

  

如果直接訪問index.html,因爲第一條規則沒有匹配,那麼會接着匹配第二條規則。

 

RewriteRule NE flag 說明

不對URL中的字符進行hexcode轉碼,比如我們傳遞一個參數,那麼

1

2

RewriteEngine On

RewriteRule ^(.*)\.htm$     /index.html#$1  [R]

訪問localhost/index.htm

可以看到#被轉移成了十六進制的%23,加上NE參數

1

2

RewriteEngine On

RewriteRule ^(.*)\.htm$     /index.html#$1  [R,NE]

  

 

 RewriteRule NC flag說明

NC是指在匹配時,不區分大小寫。因爲在Apache本身對大小寫是敏感的,

實例:

1

2

RewriteEngine On

RewriteRule ^index.htm index.html

可以看到,並沒有匹配第一條規則,因爲此時是區分大小寫的。加上NC之後,刷新:

1

2

RewriteEngine On

RewriteRule ^index.htm index.html [NC]

 

 RewriteRule G flag說明

表示請求的網頁已經失效(對應響應碼的410),並且停止後續規則的匹配

1

2

3

RewriteEngine On

RewriteRule .* - [G]

#RewriteRule .* index.html

 

 RewriteRule QSA flag說明

用於在URL中截取查詢字段,也就是保留用URL傳遞的參數,因爲默認是會將參數截取掉的

1

2

RewriteEngine On

RewriteRule ^per/(.*)$ /per.php?url=$1 [R]

  訪問localhost/per/index.htm?id=5

如果沒有QSA字段,傳遞的id=5被截取掉了。如果加上QSA字段:

1

2

RewriteEngine On

RewriteRule ^per/(.*)$ /per.php?url=$1 [R,QSA]

  再次訪問localhost/per/index.htm?id=5

 

摘要: Apache模塊 mod_rewrite 提供了一個基於正則表達式分析器的重寫引擎來實時重寫URL請求。它支持每個完整規則可以擁有不限數量的子規則以及附加條件規則的靈活而且強大的URL操作機制。這裏着重介紹 RewriteRule 規則以及參數說明。

Apache模塊 mod_rewrite 提供了一個基於正則表達式分析器的重寫引擎來實時重寫URL請求。它支持每個完整規則可以擁有不限數量的子規則以及附加條件規則的靈活而且強大的URL操作機制。此URL操作可以依賴於各種測試,比如服務器變量、環境變量、HTTP頭、時間標記,甚至各種格式的用於匹配URL組成部分的查找數據庫。

此模塊可以操作URL的所有部分(包括路徑信息部分),在服務器級的(httpd.conf)和目錄級的(.htaccess)配置都有效,還可以生成最終請求字符串。此重寫操作的結果可以是內部子處理,也可以是外部請求的轉向,甚至還可以是內部代理處理。

這裏着重介紹一下 RewriteRule 的規則以及參數說明。RewriteRule指令是重寫引擎的根本。此指令可以多次使用。每個指令定義一個簡單的重寫規則。這些規則的定義順序尤爲重要——在運行時,規則是按這個順序逐一生效的。

  1. RewriteRule Pattern Substitution [flags]

Pattern是一個作用於當前URL的perl兼容的正則表達式。"當前URL"是指該規則生效時刻的URL的值。它可能與被請求的URL截然不同,因爲其他規則可能在此之前已經發生匹配並對它做了改動。

Substitution是當原始URL與Pattern相匹配時,用來替代(或替換)的字符串。除了純文本,還可以包含:
對Pattern的反向引用($N) 
對最後匹配的RewriteCond的反向引用(%N) 
規則條件測試字符串(%{VARNAME})中的服務器變量 
映射函數調用(${mapname:key|default})

[flags]標記作爲RewriteRule指令的第三個參數,是一個包含以逗號分隔的下列標記的列表:
'chain|C'(鏈接下一規則)
此標記使當前規則與下一個規則相鏈接。它產生這樣的效果:如果一個規則被匹配,則繼續處理其後繼規則,也就是這個標記不起作用;如果該規則不被匹配,則其後繼規則將被跳過。比如,在一個目錄級規則中執行一個外部重定向時,你可能需要刪除".www"(此處不應該出現".www")。 
'cookie|CO=NAME:VAL:domain[:lifetime[:path]]'(設置cookie)
在客戶端設置一個cookie。cookie的名稱是NAME,值是VAL。domain是該cookie的域,比如'.apache.org',可選的lifetime是cookie的有效期(分鐘),可選的path是cookie的路徑。 
'env|E=VAR:VAL'(設置環境變量)
此標記將環境變量VAR的值爲VAL,VAL可以包含可擴展的正則表達式反向引用($N和%N)。此標記可以多次使用以設置多個變量。這些變量可以在其後許多情況下被間接引用,通常是在XSSI(<!--#echo var="VAR"-->)或CGI($ENV{'VAR'})中,也可以在後繼的RewriteCond指令的CondPattern參數中通過%{ENV:VAR}引用。使用它可以記住從URL中剝離的信息。 
'forbidden|F'(強制禁止URL)
強制禁止當前URL,也就是立即反饋一個HTTP響應碼403(被禁止的)。使用這個標記,可以鏈接若干個RewriteConds來有條件地阻塞某些URL。 
'gone|G'(強制廢棄URL)
強制當前URL爲已廢棄,也就是立即反饋一個HTTP響應碼410(已廢棄的)。使用這個標記,可以標明頁面已經被廢棄而不存在了。 
'handler|H=Content-handler'(強制指定內容處理器)
強自制定目標文件的內容處理器爲Content-handler。例如,用來模擬mod_alias模塊的ScriptAlias指令,以強制映射文件夾內的所有文件都由"cgi-script"處理器處理。 
'last|L'(結尾規則)
立即停止重寫操作,並不再應用其他重寫規則。它對應於Perl中的last命令或C語言中的break命令。這個標記用於阻止當前已被重寫的URL被後繼規則再次重寫。例如,使用它可以重寫根路徑的URL('/')爲實際存在的URL(比如:'/e/www/')。 
'next|N'(從頭再來)
重新執行重寫操作(從第一個規則重新開始)。此時再次進行處理的URL已經不是原始的URL了,而是經最後一個重寫規則處理過的URL。它對應於Perl中的next命令或C語言中的continue命令。此標記可以重新開始重寫操作(立即回到循環的開頭)。但是要小心,不要製造死循環! 
'nocase|NC'(忽略大小寫)
它使Pattern忽略大小寫,也就是在Pattern與當前URL匹配時,'A-Z'和'a-z'沒有區別。 
'noescape|NE'(在輸出中不對URI進行轉義)
此標記阻止mod_rewrite對重寫結果應用常規的URI轉義規則。 一般情況下,特殊字符('%', '$', ';'等)會被轉義爲等值的十六進制編碼('%25', '%24', '%3B'等)。此標記可以阻止這樣的轉義,以允許百分號等符號出現在輸出中,比如:

  1. RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE]

可以使'/foo/zed轉向到一個安全的請求'/bar?arg=P1=zed'。 
'nosubreq|NS'(不對內部子請求進行處理)
在當前請求是一個內部子請求時,此標記強制重寫引擎跳過該重寫規則。比如,在mod_include試圖搜索目錄默認文件(index.xxx)時,Apache會在內部產生子請求。對於子請求,重寫規則不一定有用,而且如果整個規則集都起作用,它甚至可能會引發錯誤。所以,可以用這個標記來排除某些規則。
使用原則:如果你爲URL添加了CGI腳本前綴,以強制它們由CGI腳本處理,但對子請求處理的出錯率(或者資源開銷)很高,在這種情況下,可以使用這個標記。 
'proxy|P'(強制爲代理)
此標記使替換成分被內部地強制作爲代理請求發送,並立即中斷重寫處理,然後把處理移交給mod_proxy模塊。你必須確保此替換串是一個能夠被mod_proxy處理的有效URI(比如以http://hostname開頭),否則將得到一個代理模塊返回的錯誤。使用這個標記,可以把某些遠程成分映射到本地服務器域名空間,從而增強了ProxyPass指令的功能。 
注意:要使用這個功能,必須已經啓用了mod_proxy模塊。
'passthrough|PT'(移交給下一個處理器)
此標記強制重寫引擎將內部request_rec結構中的uri字段設置爲filename字段的值,這個小小的修改使得RewriteRule指令的輸出能夠被(從URI轉換到文件名的)Alias, ScriptAlias, Redirect等指令進行後續處理[原文:This flag is just a hack to enable post-processing of the output of RewriteRule directives, using Alias, ScriptAlias, Redirect, and other directives from various URI-to-filename translators.]。舉一個能說明其含義的例子: 如果要將/abc重寫爲/def, 然後再使用mod_alias將/def轉換爲/ghi,可以這樣:

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

如果省略了PT標記,雖然將uri=/abc/...重寫爲filename=/def/...的部分運作正常,但是後續的mod_alias在試圖將URI轉換到文件名時會遭遇失效。 
注意:如果需要混合使用多個將URI轉換到文件名的模塊時,就必須使用這個標記。。此處混合使用mod_alias和mod_rewrite就是個典型的例子。
'qsappend|QSA'(追加查詢字符串)
此標記強制重寫引擎在已有的替換字符串中追加一個查詢字符串,而不是簡單的替換。如果需要通過重寫規則在請求串中增加信息,就可以使用這個標記。 
'redirect|R [=code]'(強制重定向)
若Substitution以http://thishost[:thisport]/(使新的URL成爲一個URI)開頭,可以強制性執行一個外部重定向。如果沒有指定code,則產生一個HTTP響應碼302(臨時性移動)。如果需要使用在300-400範圍內的其他響應代碼,只需在此指定即可(或使用下列符號名稱之一:temp(默認), permanent, seeother)。使用它可以把規範化的URL反饋給客戶端,如將"/~"重寫爲"/u/",或始終對/u/user加上斜槓,等等。
注意:在使用這個標記時,必須確保該替換字段是一個有效的URL。否則,它會指向一個無效的位置!並且要記住,此標記本身只是對URL加上http://thishost[:thisport]/前綴,重寫操作仍然會繼續進行。通常,你還會希望停止重寫操作而立即重定向,那麼就還需要使用'L'標記。 
'skip|S=num'(跳過後繼規則)
此標記強制重寫引擎跳過當前匹配規則之後的num個規則。它可以模擬if-then-else結構:最後一個規則是then從句,而被跳過的skip=N個規則是else從句。注意:它和'chain|C'標記是不同的! 
'type|T=MIME-type'(強制MIME類型)
強制目標文件的MIME類型爲MIME-type,可以用來基於某些特定條件強制設置內容類型。比如,下面的指令可以讓.php文件在以.phps擴展名調用的情況下由mod_php按照PHP源代碼的MIME類型(application/x-httpd-php-source)顯示:

  1. RewriteRule ^(.+\.php)s$ $1 [T=application/x-httpd-php-source]

 

RewriteRule example

1.If http://example.com/foo/bar does not exist, redirect to http://other.example.com/foo/bar. (Put this in an .htaccess file in your top-level web directory.)

  1. # .htaccess in root of example.com
  2. RewriteEngine On
  3. RewriteCond %{REQUEST_FILENAME} !-f
  4. RewriteCond %{REQUEST_FILENAME} !-d
  5. RewriteRule ^(.*)$ http://other.example.com/$1 [R]

2. Handle all requests for top-level .html files and files with no extensions (http://example.com/foo,http://example.com/foo.html) with a single PHP program /foo/show.php. Also, ignore trailing characters in set { : ; , . } so URLs like "http://example.com/foo." can be copied-n-pasted from plain text sentences by inattentive users.

  1. # .htaccess in root of example.com
  2. RewriteRule ^/?([^/]*\.html?|[^\./]*)[:;,\.]*$ /foo/show.php [L,NS]

Examples:

  1. http://www.updateweb.cn/rewriterule
  2. http://www.updateweb.cn/rewriterule.html;

3. Redirect GET requests for http://example.com/foo/bar to http://example.com/bar (and /foo/bar.html to /bar.html). Handle POST requests with PHP program rather than attempting to redirect a POST (which is unlikely to work well).

  1. # .htaccess in foo folder in example.com's document root
  2. RewriteEngine On
  3. RewriteCond %{REQUEST_METHOD} GET
  4. RewriteRule ^/?([^/]*\.html?|[^\./]*)[:;,\.]*$ /$1 [R,L,NS]
  5. RewriteCond %{REQUEST_METHOD} POST
  6. RewriteRule ^/?([^/]*\.html?|[^\./]*)[:;,\.]*$ /foo/show.php [L,NS]

Examples:

  1. http://updateweb.cn/w/rewriterule
  2. http://updateweb.cn/w/rewriterule.html;

Apache Rewrite 規則詳解

1、Rewrite規則簡介:

Rewirte主要的功能就是實現URL的跳轉,它的正則表達式是基於Perl語言。可基於服務器級的(httpd.conf)和目錄級的(.htaccess)兩種方式。如果要想用到rewrite模塊,必須先安裝或加載rewrite模塊。方法有兩種一種是編譯apache的時候就直接安裝rewrite模塊,別一種是編譯apache時以DSO模式安裝apache,然後再利用源碼和apxs來安裝rewrite模塊。

基於服務器級的(httpd.conf)有兩種方法,一種是在httpd.conf的全局下直接利用RewriteEngine on來打開rewrite功能;另一種是在局部裏利用RewriteEngine on來打開rewrite功能,下面將會舉例說明,需要注意的是,必須在每個virtualhost裏用RewriteEngine on來打開rewrite功能。否則virtualhost裏沒有RewriteEngine on它裏面的規則也不會生效。

基於目錄級的(.htaccess),要注意一點那就是必須打開此目錄的FollowSymLinks屬性且在.htaccess裏要聲明RewriteEngine on。

2、舉例說明:

下面是在一個虛擬主機裏定義的規則。功能是把client請求的主機前綴不是www.updateweb.cn和203.81.23.202都跳轉到主機前綴爲http://www.updateweb.cn,避免當用戶在地址欄寫入http://updateweb.cn時不能以會員方式登錄網站。

  1. NameVirtualHost 192.168.100.8:80
  2.  
  3. ServerAdmin
  4. DocumentRoot "/web/webapp"
  5. ServerName www.colorme.com.cn
  6. ServerName colorme.com.cn
  7. RewriteEngine on #打開rewirte功能
  8. RewriteCond %{HTTP_HOST} !^www.updateweb.cn [NC] #聲明Client請求的主機中前綴不是]的意思是忽略大小寫
  9. RewriteCond %{HTTP_HOST} !^203.81.23.202 [NC] #聲明Client請求的主機中前綴不是203.81.23.202,[NC]的意思是忽略大小寫
  10. RewriteCond %{HTTP_HOST} !^$ #聲明Client請求的主機中前綴不爲空,[NC]的意思是忽略大小寫
  11. RewriteRule ^/(.*) http://www.updateweb.cn/ [L] #含義是如果Client請求的主機中的前綴符合上述條件,則直接進行跳轉到]意味着立即停止重寫操作,並不再應用其他重寫規則。這裏的.*是指匹配所有URL中不包含換行字符,()括號的功能是把所有的字符做一個標記,以便於後面的應用.就是引用前面裏的(.*)字符。


例二.將輸入 folio.test.com 的域名時跳轉到profile.test.com

  1. listen 8080
  2. NameVirtualHost 10.122.89.106:8080
  3. ServerAdmin
  4. DocumentRoot "/usr/local/www/apache22/data1/"
  5. ServerName profile.test.com
  6. RewriteEngine on
  7. RewriteCond %{HTTP_HOST} ^www.updateweb.cn[NC]
  8. RewriteRule ^/(.*) http://www.updateweb.cn/ [L]

3.Apache mod_rewrite規則重寫的標誌一覽

1) R[=code](force redirect) 強制外部重定向
強制在替代字符串加上http://thishost[:thisport]/前綴重定向到外部的URL.如果code不指定,將用缺省的302 HTTP狀態碼。
2) F(force URL to be forbidden)禁用URL,返回403HTTP狀態碼。
3) G(force URL to be gone) 強制URL爲GONE,返回410HTTP狀態碼。
4) P(force proxy) 強制使用代理轉發。
5) L(last rule) 表明當前規則是最後一條規則,停止分析以後規則的重寫。
6) N(next round) 重新從第一條規則開始運行重寫過程。
7) C(chained with next rule) 與下一條規則關聯

如果規則匹配則正常處理,該標誌無效,如果不匹配,那麼下面所有關聯的規則都跳過。

8) T=MIME-type(force MIME type) 強制MIME類型
9) NS (used only if no internal sub-request) 只用於不是內部子請求
10) NC(no case) 不區分大小寫
11) QSA(query string append) 追加請求字符串
12) NE(no URI escaping of output) 不在輸出轉義特殊字符
例如:RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE] 將能正確的將/foo/zoo轉換成/bar?arg=P1=zed
13) PT(pass through to next handler) 傳遞給下一個處理
例如:
RewriteRule ^/abc(.*) /def$1 [PT] # 將會交給/def規則處理
Alias /def /ghi 
14) S=num(skip next rule(s)) 跳過num條規則
15) E=VAR:VAL(set environment variable) 設置環境變量

4.Apache rewrite例子集合

在 httpd 中將一個域名轉發到另一個域名虛擬主機世界近期更換了域名,新域名爲 www.updateweb.cn, 更加簡短好記。這時需要將原來的域名updateweb.cn, 以及論壇所在地址 updateweb.cn/forums/定向到新的域名,以便用戶可以找到,並且使原來的論壇 URL 繼續有效而不出現 404 未找到,比如原來的http://www.updateweb.cn/forums/-f60.html, 讓它在新的域名下繼續有效,點擊後轉發到http://bbs.updateweb.cn/-f60.html, 這就需要用 apache 的 Mod_rewrite 功能來實現。

在中添加下面的重定向規則:

  1. RewriteEngine On
  2. # Redirect webhosting-world.com/forums to bbs.wbhw.com
  3. RewriteCond %{REQUEST_URI} ^/forums/
  4. RewriteRule /forums/(.*) http://bbs.wbhw.com/$1 [R=permanent,L]
  5. # Redirect webhosting-world.com to wbhw.com
  6. RewriteCond %{REQUEST_URI} !^/forums/
  7. RewriteRule /(.*) http://www.wbhw.com/$1 [R=permanent,L]

添加了上面的規則以後, 裏的全部內容如下:

  1. ServerAlias webhosting-world.com
  2. ServerAdmin [email protected]
  3. DocumentRoot /path/to/webhosting-world/root
  4. ServerName www.webhosting-world.com
  5. RewriteEngine On
  6. # Redirect webhosting-world.com/forums to bbs.wbhw.com
  7. RewriteCond %{REQUEST_URI} ^/forums/
  8. RewriteRule /forums/(.*) http://bbs.wbhw.com/$1 [R=permanent,L]
  9. # Redirect webhosting-world.com to wbhw.com
  10. RewriteCond %{REQUEST_URI} !^/forums/
  11. RewriteRule /(.*) http://www.wbhw.com/$1 [R=permanent,L]

URL重定向

例子一:

1.http://www.zzz.com/xxx.php-> http://www.taobaoxs.com/xxx/
2.http://yyy.zzz.com-> http://www.taobaoxs.com/user.php?username=yyy 的功能

  1. RewriteEngine On
  2. RewriteCond %{HTTP_HOST} ^www.taobaoxs.com
  3. RewriteCond %{REQUEST_URI} !^user\.php$
  4. RewriteCond %{REQUEST_URI} \.php$
  5. RewriteRule (.*)\.php$ http://www.taobaoxs.com/$1/ [R]
  6. RewriteCond %{HTTP_HOST} !^www.taobaoxs.com
  7. RewriteRule ^(.+) %{HTTP_HOST} [C]
  8. RewriteRule ^([^\.]+)\.zzz\.com http://www.taobaoxs.com/user.php?username=$1

例子二:

/type.php?typeid=* --> /type*.html
/type.php?typeid=*&page=* --> /type*page*.html

  1. RewriteRule ^/type([0-9]+).html$ /type.php?typeid=$1 [PT]
  2. RewriteRule ^/type([0-9]+)page([0-9]+).html$ /type.php?typeid=$1&page=$2 [PT]

5.使用Apache的URL Rewrite配置多用戶虛擬服務器

要實現這個功能,首先要在DNS服務器上打開域名的泛域名解析(自己做或者找域名服務商做)。比如,我就把 *.semcase.com和 *.semcase.cn全部解析到了我的這臺Linux Server上。

然後,看一下我的Apache中關於*.semcase.com的虛擬主機的設定。

  1. #*.com,*.osall.net
  2.  
  3. ServerAdmin
  4. DocumentRoot /home/www/www.taobaoxs.com
  5. ServerName dns.semcase.com
  6. ServerAlias dns.semcase.com taobaoxs.com semcase.net *.taobaoxs.com *.semcase.net
  7. CustomLog /var/log/httpd/osa/access_log.log" common
  8. ErrorLog /var/log/httpd/osa/error_log.log"
  9. AllowOverride None
  10. Order deny,allow
  11. #AddDefaultCharset GB2312
  12.  
  13.  
  14. RewriteEngine on
  15. RewriteCond %{HTTP_HOST} ^[^.]+\.osall\.(com|net)$
  16. RewriteRule ^(.+) %{HTTP_HOST}$1 [C]
  17. RewriteRule ^([^.]+)\.osall\.(com|net)(.*)$
  18. /home/www/www.semcase.com/sylvan$3?un=$1&%{QUERY_STRING} [L]

在這段設定中,我把*.semcase.net和*.semcase.com 的Document Root都設定到了 /home/www/www.taobaoxs.com

但是,繼續看下去,看到...配置了嗎?在這裏我就配置了URL Rewrite規則。
RewriteEngine on #打開URL Rewrite功能
RewriteCond %{HTTP_HOST} ^[^.]+.osall.(com|net)$ #匹配條件,如果用戶輸入的URL中主機名是類似 xxxx.semcase.com 或者 xxxx.semcase.cn 就執行下面一句
RewriteRule ^(.+) %{HTTP_HOST}$1 [C] #把用戶輸入完整的地址(GET方式的參數除外)作爲參數傳給下一個規則,[C]是Chain串聯下一個規則的意思
RewriteRule ^([^.]+).osall.(com|net)(.*)$ /home/www/dev.semcase.com/sylvan$3?un=$1&%{QUERY_STRING} [L]
# 最關鍵的是這一句,使用證則表達式解析用戶輸入的URL地址,把主機名中的用戶名信息作爲名爲un的參數傳給/home/www/dev.semcase.com目錄下的腳本,並在後面跟上用戶輸入的GET方式的傳入參數。並指明這是最後一條規則([L]規則)。注意,在這一句中指明的重寫後的地址用的是服務器上的絕對路徑,這是內部跳轉。如果使用http://xxxx這樣的URL格式,則被稱爲外部跳轉。使用外部跳轉的話,瀏覽着的瀏覽器中的URL地址會改變成新的地址,而使用內部跳轉則瀏覽器中的地址不發生改變,看上去更像實際的二級域名虛擬服務器。

這樣設置後,重啓Apache服務器,測試一下,就大功告成了!

13 個mod_rewrite 應用舉例

1.給子域名加www標記 
RewriteCond %{HTTP_HOST} ^([a-z.]+)?example\.com$ [NC] 
RewriteCond %{HTTP_HOST} !^www\. [NC] 
RewriteRule .? http://www.%1example.com%{REQUEST_URI} [R=301,L] 
這個規則抓取二級域名的%1變量,如果不是以www開始,那麼就加www,以前的域名以及{REQUEST_URI}會跟在其後。

2.去掉域名中的www標記 
RewriteCond %{HTTP_HOST} !^example\.com$ [NC] 
RewriteRule .? http://example.com%{REQUEST_URI} [R=301,L]

3.去掉www標記,但是保存子域名 
RewriteCond %{HTTP_HOST} ^www\.(([a-z0-9_]+\.)?example\.com)$ [NC] 
RewriteRule .? http://%1%{REQUEST_URI} [R=301,L]
這裏,當匹配到1%變量以後,子域名纔會在%2(內部原子)中抓取到,而我們需要的正是這個%1變量。 

4.防止圖片盜鏈 
一些站長不擇手段的將你的圖片盜鏈在他們網站上,耗費你的帶寬。你可以加一下代碼阻止這種行爲。 
RewriteCond %{HTTP_REFERER} !^$ 
RewriteCond %{HTTP_REFERER} !^http://(www\.)?example\.com/ [NC] 
RewriteRule \.(gif|jpg|png)$ - [F] 
如果{HTTP_REFERER}值不爲空,或者不是來自你自己的域名,這個規則用[F]FLAG阻止以gif|jpg|png 結尾的URL 
如果對這種盜鏈你是堅決鄙視的,你還可以改變圖片,讓訪問盜鏈網站的用戶知道該網站正在盜用你的圖片。 
RewriteCond %{HTTP_REFERER} !^$ 
RewriteCond %{HTTP_REFERER} !^http://(www\.)?example\.com/.*$ [NC] 
RewriteRule \.(gif|jpg|png)$ 你的圖片地址 [R=301,L] 
除了阻止圖片盜鏈鏈接,以上規則將其盜鏈的圖片全部替換成了你設置的圖片。 
你還可以阻止特定域名盜鏈你的圖片: 
RewriteCond %{HTTP_REFERER} !^http://(www\.)?leech_site\.com/ [NC] 
RewriteRule \.(gif|jpg|png)$ - [F,L]
這個規則將阻止域名黑名單上所有的圖片鏈接請求。 
當然以上這些規則都是以{HTTP_REFERER}獲取域名爲基礎的,如果你想改用成IP地址,用{REMOTE_ADDR}就可以了。

5.如果文件不存在重定向到404頁面 
如果你的主機沒有提供404頁面重定向服務,那麼我們自己創建。 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule .? /404.php [L] 
這裏-f匹配的是存在的文件名,-d匹配的存在的路徑名。這段代碼在進行404重定向之前,會判斷你的文件名以及路徑名是否存在。你還可以在404頁面上加一個?url=$1參數: 
RewriteRule ^/?(.*)$ /404.php?url=$1 [L]
這樣,你的404頁面就可以做一些其他的事情,例如默認信心,發一個郵件提醒,加一個搜索,等等。

6.重命名目錄
如果你想在網站上重命名目錄,試試這個: 
RewriteRule ^/?old_directory/([a-z/.]+)$ new_directory/$1 [R=301,L]
在規則裏我添加了一個“.”(注意不是代表得所有字符,前面有轉義符)來匹配文件的後綴名。 

7.將.html後綴名轉換成.php
前提是.html文件能繼續訪問的情況下,更新你的網站鏈接。 
RewriteRule ^/?([a-z/]+)\.html$ $1.php [L]
這不是一個網頁重定向,所以訪問者是不可見的。讓他作爲一個永久重定向(可見的),將FLAG修改[R=301,L]。 

8.創建無文件後綴名鏈接
如果你想使你的PHP網站的鏈接更加簡潔易記-或者隱藏文件的後綴名,試試這個: 
RewriteRule ^/?([a-z]+)$ $1.php [L]
如果網站混有PHP以及HTML文件,你可以用RewriteCond先判斷該後綴的文件是否存在,然後進行替換: 
RewriteCond %{REQUEST_FILENAME}.php -f 
RewriteRule ^/?([a-zA-Z0-9]+)$ $1.php [L] 
RewriteCond %{REQUEST_FILENAME}.html -f 
RewriteRule ^/?([a-zA-Z0-9]+)$ $1.html [L]
如果文件是以.php爲後綴,這條規則將被執行。

9.檢查查詢變量裏的特定參數
如果在URL裏面有一個特殊的參數,你可用RewriteCond鑑別其是否存在: 
RewriteCond %{QUERY_STRING} !uniquekey= 
RewriteRule ^/?script_that_requires_uniquekey\.php$ other_script.php [QSA,L]
以上規則將檢查{QUERY_STRING}裏面的uniquekey參數是否存在,如果{REQUEST_URI}值爲script_that_requires_uniquekey,將會定向到新的URL。 

10.刪除查詢變量
Apache的mod_rewrite模塊會自動辨識查詢變量,除非你做了以下改動: 
a).分配一個新的查詢參數(你可以用[QSA,L]FLAG保存最初的查詢變量) 
b).在文件名後面加一個“?”(比如index.php?)。符號“?”不會在瀏覽器的地址欄裏顯示。

11.用新的格式展示當前URI 
如果這就是我們當前正在運行的URLs:/index.php?id=nnnn。我們非常希望將其更改成/nnnn並且讓搜索引擎以新格式展現。首先,我們爲了讓搜索引擎更新成新的,得將舊的URLs重定向到新的格式,但是,我們還得保證以前的index.php照樣能夠運行。是不是被我搞迷糊了? 
實現以上功能,訣竅就在於在查詢變量中加了一個訪問者看不到的標記符“marker”。我們只將查詢變量中沒有出現“marker”標記的鏈接進行重定向,然後將原有的鏈接替換成新的格式,並且通過[QSA]FLAG在已有的參數加一個“marker”標記。以下爲實現的方式: 
RewriteCond %{QUERY_STRING} !marker 
RewriteCond %{QUERY_STRING} id=([-a-zA-Z0-9_+]+) 
RewriteRule ^/?index\.php$ %1? [R=301,L] 
RewriteRule ^/?([-a-zA-Z0-9_+]+)$ index.php?marker &id=$1 [L]
這裏,原先的URL:http://www.example.com/index.php?id=nnnn,不包含marker,所以被第一個規則永久重定向到http://www.example.com/nnnn,第二個規則將http://www.example.com/nnnn反定向到http://www.example.com/index.php?marker &id=nnnn,並且加了marker以及id=nnnn兩個變量,最後mod_rewrite就開始進行處理過程。
第二次匹配,marker被匹配,所以忽略第一條規則,這裏有一個“.”字符會出現在http://www.example.com/index.php?marker &id=nnnn中,所以第二條規則也會被忽略,這樣我們就完成了。
注意,這個解決方案要求Apache的一些擴展功能,所以如果你的網站放於在共享主機中會遇到很多障礙。

12.保證安全服務啓用
Apache可以用兩種方法辨別你是否開啓了安全服務,分別引用{HTTPS}和{SERVER_PORT}變量: 
RewriteCond %{REQUEST_URI} ^secure_page\.php$ 
RewriteCond %{HTTPS} !on 
RewriteRule ^/?(secure_page\.php)$ https://www.taobaoxs.com/$1 [R=301,L]
以上規則測試{REQUEST_URI}值是否等於我們的安全頁代碼,並且{HTTPS}不等於on。如果這兩個條件同時滿足,請求將被重定向到安全服務URI.另外你可用{SERVER_PORT}做同樣的測試,443是常用的安全服務端口 
RewriteCond %{REQUEST_URI} ^secure_page\.php$ 
RewriteCond %{SERVER_PORT} !^443$ 
RewriteRule ^/?(secure_page\.php)$ https://www.taobaoxs.com/$1 [R=301,L]

13.在特定的頁面上強制執行安全服務 
遇到同一個服務器根目錄下分別有一個安全服務域名和一個非安全服務域名,所以你就需要用RewriteCond 判斷安全服務端口是否佔用,並且只將以下列表的頁面要求爲安全服務: 
RewriteCond %{SERVER_PORT} !^443$ 
RewriteRule ^/?(page1|page2|page3|page4|page5)$ https://www.taobaoxs.com/%1 [R=301,L] 
以下是怎樣將沒有設置成安全服務的頁面返回到80端口: 
RewriteCond %{ SERVER_PORT } ^443$ 
RewriteRule !^/?(page6|page7|page8|page9)$ taobaoxs.com%{REQUEST_URI} [R=301,L]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章