ISAPI_Rewrite 是一個較為好用的URL重寫元件,安裝和配置都比較簡單, 防盜鍊的設定 也極其簡單。
問題
如何擷取被ISAPI_Rewrite重寫後的URL。
測試環境:IIS6中使用ISAPI_Rewrite對Default.aspx進行重寫,重寫後的位址為:Index-After-ReWriter.html。
需要擷取重寫後的位址,即Index-After-ReWriter.html。
一些彎路
首先想到的就是
Request對象,如
Request.Url和
Request.RawUrl。
測試後發現擷取到的位址都是Default.aspx。
上網找了找ISAPI_Rewrite的處理流程圖,找到了下面這個圖檔。

那麼再來看下IIS處理aspx頁面的流程圖。
在送出到ASP.NET子產品處理前,同樣都是
ISAPI擴充的aspnet_isapi.dll和ISAPI_Rewrite.dll,從第一張圖中可以看出ISAPI_Rewrite.dll解析了重寫後的URL(即測試環境中的Index-After-ReWriter.html),即解析成Default.aspx後再轉由aspnet_isapi.dll進行處理。真的是這樣嗎?去IIS中去一看便知。
注意是在IIS中的網站全局屬性中檢視,如果需要使重寫子產品對單一的網站起作用那麼需要單獨對網站進行設定。
那麼在Request對象中還會儲存有重寫後的URL位址嗎?
又上網找了找,正如博文
當你的部落格文章的作者變成“編輯整理”,你作何感想?中提到的一樣,帶來的一個現象是點了前兩頁擷取到的資訊的都是這篇文章:
使用Request.RawUrl擷取目前請求重寫(UrlRewrite)後的Url我基本保持文章中提供的源代碼測試了下。
protected override void OnInit(EventArgs e)
{
string a = Request.ServerVariables["SCRIPT_NAME"];
//string b = Request.ServerVariables["QUERY_STRING"];
//string c = Request.Url.AbsoluteUri;
//string d = Request.ServerVariables["HTTP_URL"];
string f = Request.Url.ToString();
base.OnInit(e);
}
調試了下,發現不管怎麼擷取,得到的值還是Default.aspx。:(
不過提供的源代碼中那三段莫名其妙的注釋提醒了我, 因為ISAPI_Rewrite這個元件是從Apache mod_rewrite移植過來的,那麼PHP等其他語言應該有類似的通用方法,說的時髦點就是跨平台的方法去擷取重寫後的URL位址。
解決方法
繼續去查,發現的确是這樣。
“在修改URL之前ISAPI_Rewrite會儲存原URL到Http頭,命名為X-Rewrite-URL。然後它能夠在腳本中作為HTTP_X_REWRITE_URL伺服器變量取回。因為在IIS裡,系統變量名不能被修改,是以ISAPI_Rewrite不能提供與Apache相容的變量名REQUEST_URI。如果你的應用程式的設計要依賴于REQUEST_URI變量,你必須修改它,用HTTP_X_REWRITE_URL變量來代替。”
使用抓包工具
Fiddler抓包或者加斷點檢視Request.ServerVariables的值。
發現HTTP_X_REWRITE_URL中儲存了重寫前的URL位址。
可以這樣測試一下。
protected void Page_Load(object sender, EventArgs e)
if (Request.ServerVariables["HTTP_X_REWRITE_URL"] == null) return;
Response.Write(Request.ServerVariables["HTTP_X_REWRITE_URL"]);
Response.End();
結果是這樣:
文中有些臆斷之處,還望各位大蝦不吝賜教!
作者:
Parry出處:
http://www.cnblogs.com/parry/本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。