由於我以前曾經好長一段時間都只碰 LAMP ( Linux, Apache, MySQL, PHP ),也因為這樣之前曾經接觸過 Apache 的一個很有名的模組 mod_rewrite,由於這個模組強大的 URL Rewriting 功能,讓你很輕易的就可以完成 SEO 的規劃,或是設定條件阻擋 Hot-linking 的要求,甚至於還可以做到類似 Reverse Proxy 的效果。這樣的功能在 ASP.NET 中當然也少不了,不過讓我高興的是,竟然有人實做出一個跟 mod_rewrite 設定格式幾乎相容的版本。
.NET URL Rewriter and Reverse Proxy 是一個 ASP.NET HttpModule,讓你可以處理許多 URL Rewrite (網址重寫) 的要求,例如說你原本的 ASP.NET 網址如下:
http://www.example.com/news.aspx?type=general&id=3394
可以將以上網址改寫成以下網址:
http://www.example.com/news/general/3394.aspx
要達到這樣的需求,只要透過 .NET URL Rewriter and Reverse Proxy 就可以很輕易的直接透過設定檔完成所有設定。
我這幾年寫 ASP.NET 以來,就以 URL Rewrite 這個功能來說,這一套是我最滿意的(雖然還是有瑕疵),不過對於沒有用過 mod_rewrite 的人來說,他的設定檔其實不那麼討喜,我覺得初學者要看懂怎麼使用還真不容易,就連我每次要用的時候都還是要看一下文件,不然就是抓以前的筆記起來參考才寫的出來。
當你下載 .NET URL Rewriter and Reverse Proxy 之後,有三個檔案可以用:
- url-rewiter.zip 包括所有檔案了,包括 Read Me.txt 中的安裝說明。
- Read Me.txt 包括此元件完整的說明,包括安裝、設定、範例等資料。
- ManagedFusion.Rewriter.rules 包括一個範例的設定檔
我就來解釋一下預設的範例設定檔吧:
# deny access to evil robots site rippers offline browsers and other nasty scum
RewriteCond %{HTTP_USER_AGENT} ^Anarchie [OR]
RewriteCond %{HTTP_USER_AGENT} ^ASPSeek [OR]
RewriteCond %{HTTP_USER_AGENT} ^attach [OR]
RewriteCond %{HTTP_USER_AGENT} ^autoemailspider [OR]
RewriteCond %{HTTP_USER_AGENT} ^Xaldon\ WebSpider [OR]
RewriteCond %{HTTP_USER_AGENT} ^Xenu [OR]
RewriteCond %{HTTP_USER_AGENT} ^Zeus.*Webster [OR]
RewriteCond %{HTTP_USER_AGENT} ^Zeus
RewriteRule ^.* - [F,L]
RewriteCond 是指「套用 RewriteRule 的條件」,條件成立才會套用緊接著的 RewriteRule 設定,而最後的中括弧包起來的設定是指這個條件的 "特性",例如這裡的 [OR] 就代表下面還有個 RewriteCond 並且要做 OR 邏輯運算。而最後的 RewriteRule 就是設定比對的 Pattern (RegEx),以及要將網址替代成什麼結果,而重要的就是最後中括弧包起來的設定了,這裡的 F 代表 forbidden (拒絕存取),而 L 代表 Last (最後一個 RewriteRule),只要有 L 出現,就代表若此規則比對成功,就不再比對下去了(包括 Pattern 比對成功,以及 RewriteCond 的結果也是 True 才行)。
底下有張圖說明了這裡的 mod_rewrite 中套用 RewriteRule 比對的流程圖,所有的 RewriteRule 套用完成後,被修改後的網址其實會再被下一個規則比對過,並且再次替代,除非有上一段指定的 [L] 出現才會停止比對。
我接著解釋下去:
# redirect to canonical domain
RewriteCond %{HTTP_HOST} !^blog\.miniasp\.com [NC]
RewriteRule (.*) http://blog.miniasp.com/$1 [R=301,L]
這裡的 RewriteCond 中 %{HTTP_HOST} 指的是 URL 中 Hostname 的部分,如果比對不等於 blog.miniasp.com 的時候就回傳 True,其中的 [NC] 代表 no case (不區分英文字母大小寫)。而 RewriteRule 的 (.*) 就是指完整的 URL Path,這裡的 http://blog.miniasp.com/$1 就代表將所有比對到的 URL Path 接在 http://blog.miniasp.com/ 後面,最後的 R=301 代表 Moved Permanently Redirect (永遠重新轉向),並且回應 HTTP Status Code 為 301。
例如:若你是透過 http://www.blog.miniasp.com/contact.aspx 連到我的網站,會被自動轉址到 http://blog.miniasp.com/contact.aspx。(這裡是明確指定「轉址」,所以並非「URL Rewrite」喔)
剩下的 RewriteRule 我一次講完好了:
# add a trailing slash
RewriteRule ^/([^.?]+[^.?/])$ /$1/ [I,R=301]
# remove index pages from URLs
RewriteRule (.*)/default.htm$ $1/ [I,R=301]
RewriteRule (.*)/default.aspx$ $1/ [I,R=301]
RewriteRule (.*)/index.htm$ $1/ [I,R=301]
RewriteRule (.*)/index.html$ $1/ [I,R=301]
說實在的,這裡的 I 是什麼意思我還真查不到呢,mod_rewrite 文件中也沒有這個的定義。但我想其他部分應該難不倒各位了吧,熟悉 Reqular Expression 的人一看就知道意思了。
相關連結