﻿# 介紹ASP.NET元件：.NET URL Rewriter and Reverse Proxy

由於我以前曾經好長一段時間都只碰 [LAMP](http://en.wikipedia.org/wiki/LAMP_stack) ( Linux, Apache, MySQL, PHP )，也因為這樣之前曾經接觸過 Apache 的一個很有名的模組 [mod\_rewrite](http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html)，由於這個模組強大的 [URL Rewriting](http://zh.wikipedia.org/wiki/URL_Rewriting) 功能，讓你很輕易的就可以完成 SEO 的規劃，或是設定條件阻擋 [Hot-linking](http://simple.wikipedia.org/wiki/Hot-linking) 的要求，甚至於還可以做到類似 Reverse Proxy 的效果。這樣的功能在 ASP.NET 中當然也少不了，不過讓我高興的是，竟然有人實做出一個跟 mod\_rewrite 設定格式幾乎相容的版本。

[.NET URL Rewriter and Reverse Proxy](http://www.codeplex.com/urlrewriter) 是一個 ASP.NET [HttpModule](http://msdn.microsoft.com/zh-tw/library/aa720143\(VS.71\).aspx)，讓你可以處理許多 [URL Rewrite](http://en.wikipedia.org/wiki/Rewrite_engine) (網址重寫) 的要求，例如說你原本的 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](http://www.codeplex.com/urlrewriter) 就可以很輕易的直接透過設定檔完成所有設定。

我這幾年寫 ASP.NET 以來，就以 URL Rewrite 這個功能來說，這一套是我最滿意的（雖然還是有瑕疵），不過對於沒有用過 mod\_rewrite 的人來說，他的設定檔其實不那麼討喜，我覺得初學者要看懂怎麼使用還真不容易，就連我每次要用的時候都還是要看一下文件，不然就是抓以前的筆記起來參考才寫的出來。

當你下載 [.NET URL Rewriter and Reverse Proxy](http://www.codeplex.com/urlrewriter) 之後，有三個檔案可以用：

1.  url-rewiter.zip 包括所有檔案了，包括 Read Me.txt 中的安裝說明。
2.  Read Me.txt 包括此元件完整的說明，包括安裝、設定、範例等資料。
3.  ManagedFusion.Rewriter.rules 包括一個範例的設定檔

![.NET URL Rewriter and Reverse Proxy](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/4305de10915804538c9d-image_3.png ".NET URL Rewriter and Reverse Proxy")

我就來解釋一下預設的範例設定檔吧：

```
# 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\] 出現才會停止比對。

![mod\_rewrite 中套用 RewriteRule 比對的流程圖](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/b87dada6a35980bb3a5f-image_6.png "mod_rewrite 中套用 RewriteRule 比對的流程圖")

我接著解釋下去：

```
# 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](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) 為 301。

例如：若你是透過 [http://www.blog.miniasp.com/contact.aspx](http://www.blog.miniasp.com/contact.aspx) 連到我的網站，會被自動轉址到 [http://blog.miniasp.com/contact.aspx](/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](http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html) 文件中也沒有這個的定義。但我想其他部分應該難不倒各位了吧，熟悉 Reqular Expression 的人一看就知道意思了。

**相關連結**

-   [.NET URL Rewriter and Reverse Proxy](http://www.codeplex.com/urlrewriter) on CodePlex
-   [.NET URL Rewriter and Reverse Proxy](https://web.archive.org/web/20080206131537/http://code.msdn.microsoft.com:80/urlrewriter) on MSDN Code Gallery
-   [Apache Module mod\_rewrite](http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html)
-   [URL Rewriting Guide](http://httpd.apache.org/docs/2.0/rewrite/rewrite_guide.html)
-   [URL Rewriting Guide - Advanced topics](http://httpd.apache.org/docs/2.0/rewrite/rewrite_guide_advanced.html)
