摘要:介紹如何使用 microsoft asp.net 執(zhí)行動(dòng)態(tài) url 重寫。url 重寫是截取傳入 web 請(qǐng)求并自動(dòng)將請(qǐng)求重定向到其他 url 的過(guò)程。討論實(shí)現(xiàn) url 重寫的各種技術(shù),并介紹執(zhí)行 url 重寫的一些實(shí)際情況。
返回頁(yè)首 請(qǐng)求到達(dá) iis 時(shí)將會(huì)發(fā)生什么情況 在正式研究 url 如何實(shí)現(xiàn)重寫之前,應(yīng)首先了解 microsoft® internet information services (iis) 如何處理傳入請(qǐng)求,這一點(diǎn)非常重要。當(dāng)請(qǐng)求到達(dá) iis web 服務(wù)器時(shí),iis 檢查被請(qǐng)求文件的擴(kuò)展名以確定如何處理該請(qǐng)求。iis 可以自行處理請(qǐng)求(如 html 頁(yè)面、圖像以及其他靜態(tài)內(nèi)容),或者將請(qǐng)求路由到 isapi 擴(kuò)展。(isapi 擴(kuò)展是一個(gè)處理傳入 web 請(qǐng)求的非托管編譯類。其任務(wù)是生成被請(qǐng)求資源的內(nèi)容。)
例如,當(dāng)傳入針對(duì) info.asp 網(wǎng)頁(yè)的請(qǐng)求時(shí),iis 會(huì)將此消息路由到 asp.dll isapi 擴(kuò)展。然后,該 isapi 擴(kuò)展將加載被請(qǐng)求的 asp 頁(yè)面,執(zhí)行該頁(yè)面,并將所呈現(xiàn)的 html 返回給 iis,然后,iis 將該 html 發(fā)送回請(qǐng)求客戶端。對(duì)于 asp.net 頁(yè)面,iis 會(huì)將此消息路由到 aspnet_isapi.dll isapi 擴(kuò)展。然后,aspnet_isapi.dll isapi 擴(kuò)展將處理操作傳遞給托管的 asp.net 輔助進(jìn)程,該輔助程序?qū)⑻幚碚?qǐng)求,并返回 asp.net 網(wǎng)頁(yè)的呈現(xiàn) html。
您可以自定義 iis,以指定擴(kuò)展名與 isapi 擴(kuò)展的映射關(guān)系。圖 1 顯示了 internet information services 管理工具的“應(yīng)用程序配置”對(duì)話框。請(qǐng)注意,與 asp.net 有關(guān)的擴(kuò)展名(.aspx、ascx、config、asmx、rem、cs、vb 及其他)均已映射到 aspnet_isapi.dll isapi 擴(kuò)展。
圖 1. 已配置的文件擴(kuò)展名映射
討論 iis 如何管理傳入請(qǐng)求稍稍超出了本文范圍。但是可以在 michele leroux bustamante 的文章 inside iis and asp.net 中找到對(duì)此內(nèi)容的深入討論。asp.net 引擎僅處理那些擴(kuò)展名已明確映射至 iis 中的 aspnet_isapi.dll 的傳入 web 請(qǐng)求,了解這一點(diǎn)非常重要。
雖然 isapi 篩選器可用于執(zhí)行 url 重寫,但本文將討論如何使用 asp.net 實(shí)現(xiàn) url 重寫。不過(guò),我們將對(duì)使用 isapi 篩選器與使用 asp.net 中的技術(shù)實(shí)現(xiàn) url 重寫進(jìn)行權(quán)衡。
請(qǐng)求進(jìn)入 asp.net 引擎時(shí)將會(huì)發(fā)生什么情況 在 asp.net 之前,需要使用 isapi 篩選器來(lái)實(shí)現(xiàn) iis web 服務(wù)器上的 url 重寫。由于 asp.net 引擎與 iis 非常相似,因此可以使用 asp.net 進(jìn)行 url 重寫。存在相似之處的原因在于 asp.net 引擎可以實(shí)現(xiàn)以下功能:
asp.net 包括許多內(nèi)置的 http 處理程序。例如,pagehandlerfactory 用于呈現(xiàn) asp.net 網(wǎng)頁(yè)。webservicehandlerfactory 用于呈現(xiàn) asp.net web 服務(wù)的響應(yīng) soap 信封。tracehandler 將向 trace.axd 呈現(xiàn)請(qǐng)求的 html 標(biāo)記。
public abstract class basemodulerewriter : ihttpmodule { public virtual void init(httpapplication app) { // 警告!此代碼不適用于 windows 身份驗(yàn)證! // 如果使用 windows 身份驗(yàn)證, // 請(qǐng)改為 app.beginrequest app.authorizerequest += new eventhandler(this.basemodulerewriter_authorizerequest); }
創(chuàng)建此類并對(duì)其進(jìn)行編譯之后,要在 asp.net web 應(yīng)用程序中使用它,應(yīng)首先將其添加到 web 應(yīng)用程序的 references 文件夾中。然后,要使用它來(lái)代替 htmlform 類,只需在 asp.net 網(wǎng)頁(yè)的頂部添加以下內(nèi)容即可:
blog 在當(dāng)今正變得越來(lái)越流行,似乎每個(gè)人都擁有自己的 blog。如果您不熟悉 blog:blog 是經(jīng)常更新的個(gè)人頁(yè)面,通常作為聯(lián)機(jī)期刊。大多數(shù) blog 只記錄每天發(fā)生的事情,還有一些 blog 可能關(guān)注于特定的主題(例如,電影回顧、體育團(tuán)隊(duì)或計(jì)算機(jī)技術(shù))。
注意:url 重寫引擎在 <lookfor> 元素中需要使用正則表達(dá)式模式。如果您對(duì)正則表達(dá)式不熟悉,可以閱讀我在早些時(shí)候編寫的一篇文章 an introduction to regular expressions。另外,還有一個(gè)很好的網(wǎng)站:regexlib.com,在那里您可以獲取有關(guān)常用正則表達(dá)式的幫助信息,還可以共享您自己的自定義正則表達(dá)式。
構(gòu)建必備的目錄結(jié)構(gòu) 當(dāng)請(qǐng)求 /2004/03/19.aspx 時(shí),iis 將通知 .aspx 擴(kuò)展,并將請(qǐng)求路由到 asp.net 引擎。請(qǐng)求在 asp.net 引擎的管道中移動(dòng)時(shí),url 將被重寫為 showblogcontent.aspx?year=2004&month=03&day=19,并且訪問(wèn)者會(huì)看到 2004 年 3 月 19 日的 blog 條目。但是當(dāng)用戶瀏覽到 /2004/03/ 時(shí)將會(huì)發(fā)生什么情況呢?除非有一個(gè) /2004/03/ 目錄,否則 iis 將返回一個(gè) 404 錯(cuò)誤。此外,此目錄中還需要具有 default.aspx 頁(yè)面,以便可以將請(qǐng)求傳遞給 asp.net 引擎。
很顯然,添加這樣一個(gè)目錄結(jié)構(gòu)可能是一件很痛苦的事情。解決此問(wèn)題的方法是使所有傳入的 iis 請(qǐng)求都映射到 asp.net 引擎。通過(guò)這種方法,即使訪問(wèn) url /2004/03/,iis 也會(huì)如實(shí)地將請(qǐng)求傳遞給 asp.net 引擎(即使并不存在 /2004/03/ 目錄)。但是,使用這種方法將使 asp.net 引擎負(fù)責(zé)處理到達(dá) web 服務(wù)器的所有類型的傳入請(qǐng)求,包括圖像、css 文件、外部 javascript 文件、macromedia flash 文件,等等。
對(duì)處理所有文件類型的全面討論遠(yuǎn)遠(yuǎn)超出了本文的范圍。有關(guān)使用此技術(shù)的 asp.net web 應(yīng)用程序的示例,請(qǐng)參閱 .text,一個(gè)開放源 blog 引擎。.text 可以配置為將所有請(qǐng)求均映射到 asp.net 引擎。它可以使用自定義 http 處理程序來(lái)處理生成所有文件類型的問(wèn)題,自定義 http 處理程序了解如何生成典型的靜態(tài)文件類型(圖像、css 文件,等等)。
返回頁(yè)首 結(jié)論 在本文中,我們討論了如何在 asp.net 級(jí)別通過(guò) httpcontext 類的 rewriteurl() 方法來(lái)執(zhí)行 url 重寫。正如我們所看到的,rewriteurl() 更新了特定的 httpcontext's request 屬性,從而更新了被請(qǐng)求的文件和路徑。最終結(jié)果是,從用戶角度來(lái)看,他們要訪問(wèn)某個(gè)特定的 url,但從 web 服務(wù)器端來(lái)看,被請(qǐng)求的卻是另一個(gè) url。
當(dāng)然,如果執(zhí)行 asp.net 級(jí)別的重寫,則僅當(dāng)已成功地將請(qǐng)求從 iis 傳遞給 asp.net 引擎后才會(huì)發(fā)生 url 重寫。實(shí)際上,只有用戶請(qǐng)求帶 .aspx 擴(kuò)展名的頁(yè)面時(shí)才會(huì)出現(xiàn)這種情況。但是,如果您要使用戶可以進(jìn)入實(shí)際并不存在的 url,但又希望重寫到現(xiàn)有的 asp.net 頁(yè)面,則必須創(chuàng)建虛擬目錄和 default.aspx 頁(yè)面,或者對(duì) iis 進(jìn)行配置,以使所有傳入請(qǐng)求一律被路由到 asp.net 引擎。