大叔手记(16):分析URL Routing和URL Rewriting两者之间的不同
前言
前面有2篇帖子提到了關于URL Routing的特性,但是發現有很多人誤會URL Routing就是URl Rewriting,其實2個雖然都提供相似的功能(提高友好的URL方便搜索引起收錄),但是2者的原理和運行周期是完全不一樣的,本篇文章我們就來分析一下具體有什么不同。
例子
在分析原理之前,我們先來做一個例子測試一下(IIS URL Rewrite模塊需要IIS7的支持)。
1.為Customer/1的URL建立對應的MVC程序
首先建立一個普通的MVC3程序,建立一個簡單的CustomerController以及一個簡單的Detail action,代碼如下:
public class CustomerController : Controller{
public ActionResult Detail(string id)
{
ViewBag.CustomerID = id;
return View();
}
}
我們只是簡單的接受一個ID,然后放到ViewBag里以便在view里顯示,view的代碼如下:
@{Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Detail</title>
</head>
<body>
<div>
MVC下運行結果:@ViewBag.CustomerID
</div>
</body>
</html>
2.為Customer/1的URL建立對應的web form程序
在同一個解決方案的根目錄下,建立一個Customer.aspx文件,文件代碼主要是接受一個ID參數然后顯示在頁面上,代碼:
public partial class Customer : System.Web.UI.Page{
protected void Page_Load(object sender, EventArgs e)
{
this.lblId.InnerText = Request.QueryString["id"];
}
}
html:
<form id="form1" runat="server"><div>
asp.net web form下是:<label runat="server" id="lblId"></label>
</div>
</form>
OK,我們先在Global.asax.cs里配置Customre/1的route,代碼如下:
routes.MapRoute("CustomerDetail", // Route name
"Customer/{id}", // URL with parameters
new { controller = "Customer", action = "Detail", id = UrlParameter.Optional }
);
編譯訪問,運行http://localhost/customer/123,頁面顯示結果是:
MVC下運行結果:123。
3.安裝IIS URL Rewrite
到如下地址下載并安裝IIS URL Rewrite,http://www.iis.net/download/URLRewrite 成功安裝以后,在MVC項目的web.config里配置一條URL重寫規則,代碼如下(注意是system.webServer節點哦):
<system.webServer><validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true" />
<rewrite>
<rules>
<rule name="rewrite customer">
<match url="^customer/([0-9]+)" />
<action type="Rewrite" url="customer.aspx?id={R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
該規則的意思是,將customer/1類似的請求重寫到customer.aspx?id=1上,我們編譯程序再來訪問以下http://localhost/customer/123,頁面顯示結果如下:
asp.net web form下是:123
也就是說Routing在這個時候沒起作用,因為URL Rewrite是在Routing之前將Customer/123這個地址轉發到了Customer.aspx?id=123,由aspx文件接收請求了。我們來看看2者之間到底都是在什么周期處理的。
原理周期
1. URL Rewrite
關于URL Rewrite最早見于apache web server,當時風靡一時的url重寫讓一大批使用php的人欣喜若狂啊,可惜之前由于asp.net下的實現方式特別復雜,所以很多站的基本上都沒怎么用,自從IIS.net推出正式的IIS URL Rewrite模塊以來,徹底解決了這一問題。
URL Rewrite是在request-processing pipeline的早期階段執行的,一般一個地址進來以后,該模塊會根據規則來映射到同一服務器上的另外一條新的地址,新地址在處理的時候所接受的參數和數據都是一句新地址的參數來判斷的,就比如customer.aspx?id=123,而 request里的url也是新的地址,而不是重寫之前的地址,不過用戶本身感覺不到變化,因為瀏覽器上顯示的一直是舊URL,我們來看一下他的周期圖。
URL Rewrite module是一個native的模塊,從圖可以看到他的運行周期是在Pre-begin Rquest和Begin Request之間,該模塊在根據請求的URL進行規則匹配之后,最終處理新的URL以便進入IIS pipeline的剩余周期里進行處理,就是說處理請求的HttpHandler是根據重寫以后的新URL來決定的。
2. URL Routing
URL Routing的原理是根據現有的URL來定義規則,定義每個規則所對應的HttpHandler,其本質和URL是否友好沒有關系,只是按照統一的規則去調用相對應的HttpHandler而已,找到對應的HttpHandler,處理完以后就返回結果,找不到就暴資源錯誤。
Routing是托管代碼模塊,是在Resolve Cache周期( PostResolveRequestCache事件)里注冊,然后在MapHandler周期內處理的。在PostResolveRequestCache事件里,該模塊查詢靜態集合routing表里的所有記錄里聲明的URL匹配規則,如果當前URL對應到了一個匹配的Handler,然后就使用該Handler處理結果并輸出。
兩者之間的不同
總結
兩者之間有這么多不同,那我們到底該用哪一個呢?
如果你的程序是用asp.net之外的平臺構建的,那你只能使用IIS URL Rewrite了,否則,我們建議的規則是:
當然,你也可以兩者結合起來一起用,但是用之前一定要記得上面的圖里所說明的內容:他們的執行周期不一樣。
參考地址:http://learn.iis.net/page.aspx/496/iis-url-rewriting-and-aspnet-routing/
同步與推薦
本文已同步至目錄索引:《大叔手記全集》
大叔手記:旨在記錄日常工作中的各種小技巧與資料(包括但不限于技術),如對你有用,請推薦一把,給大叔寫作的動力。
總結
以上是生活随笔為你收集整理的大叔手记(16):分析URL Routing和URL Rewriting两者之间的不同的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Korn Shell: typeset
- 下一篇: 告别苦逼的程序员生涯,我的CTO之路!