1、IIS服務器根據請求的文件的後綴名來肯定如何處理這個請求。例如.html,或.js,或.aspx…服務器獲取所請求的頁面的後綴名後,在服務器端尋找能夠處理這類後綴名的應用程序,若是IIS找不到能夠處理此類文件的應用程序,而且這個文件也沒有受到服務器端的保護(一個受保護的例子就是App_Code中的文件,一個不受保護的例子就是你的js腳本),那麼IIS就直接把這個文件返回給客戶端。html
若是服務器找到了處理此類文件的應用程序,一般稱爲ISAPI(Internet Server Application Programe Interface,互聯網服務器應用程序接口)應用程序,他實際上只是一個接口,起到一個代理的做用,它的主要工做是映射所請求的頁面(文件)和與此後綴名相對應的實際的處理程序。程序員
例如全部的.aspx文件實際上都是由aspnet_isapi.dll這個程序來處理的,當IIS把對於.aspx頁面的請求提交給了aspnet_isapi.dll之後,它就再也不關心這個請求隨後是如何處理的了。Asp.net只是服務器(IIS)的一個組成部分而已,它是一個ISAPI擴展。web
HttpRuntime類是asp.net的一個主要入口,它有一個稱做ProcessRequest的方法,這個方法以一個HttpWorkerRequest類做爲參數,HttpRuntime類幾乎包含着關於單個Http請求的全部信息:所請求的文件、服務器變量、QueryString、Http頭信息等等。Asp.net使用這些信息來加載、運行正確的文件,而且將這個請求轉換到輸出流中,通常來講,也就是HTML頁面。api
當web.config文件的內容發生改變,或者.aspx文件發生變更的時候,爲了可以卸載運行在同一個進程中的應用程序,而後再從新加載,Http請求被分放在相互隔離的應用程序域中。HTTP.SYS的內置驅動程序來監聽來自外部的HTTP請求,在操做系統啓動的時候,IIS首先在HTTP.SYS中註冊本身的虛擬路徑。瀏覽器
若是請求是一個可訪問的URL,HTTP.SYS會將這個請求交給IIS工做者進程。IIS6.0中叫作w3wp.exe,IIS5.0中叫作aspnet_wp.exe。服務器
除了映射文件與其對應的處理程序外,ISAPI還須要作一些其餘的工做:app
一、從HTTP.SYS中獲取當前的Http請求信息,而且將這些信息保存到HttpWorkerRequest類中。asp.net
二、在相互隔離的應用程序域AppDomain中加載HttpRuntimepost
三、調用 HttpRuntime的ProcessRequest方法。url
接下來纔是程序員一般編寫的代碼所完成的工做了,而後,IIS接收返回的數據流,並從新返還給 HTTP.SYS,最後,HTTP.SYS 再將這些數據返回給客戶端瀏覽器。
2、當Http請求進入Asp.net RunTime之後,它的管道由託管模塊(Managed Modules)和處理程序(Handlers)組成,而且由管道來處理這個Http請求。
按照圖中的編號瞭解數據是如何流動的:
① HttpRuntime將Http請求轉交給HttpApplication,HttpApplication表明着程序員建立的Web應用程序。HttpApplication建立針對此Http請求的HttpContext對象,這些HttpContext對象包含了關於此請求的諸多其餘對象,主要有HttpRequest、HttpResponse、HttpSessionState等。這些對象在程序中能夠經過Page類或者Context類進行訪問。
② 接下來Http請求經過一系列Module,這些Module對Http請求具備徹底的控制權。這些Module能夠作一些執行某個實際工做前的事情。
③ Http請求通過全部的Module以後,它會被HttpHandler處理。
④ HttpHandler處理完之後,Http請求再一次回到Module,此時Module能夠作一些某個工做已經完成了以後的事情。
3、Http管道中有兩個可用的接口。一個是IHttpHandler,一個是IHttpModule。經過查看「處理程序映射」,發現好多文件都交給aspnet_isapi.dll去處理了。很明顯,aspnet_isapi.dll不可能對每種文件採用同一種方式處理,因此在C:、WiNDOWS\Microsoft.NET\Framework\v2.0.50727\Config\目錄下web.config文件中的<httpHandlers>節點中將不一樣的文件類型映射給不一樣的Handler去處理,對於.aspx來講,是由System.Web.UI.Page.HandlerFactory來處理。
1 <httpHandlers>
2
3 …… 4
5 <add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True" />
6
7 <add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" validate="True" />
8
9 <add path="*.asmx" verb="*" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="False" />
10
11 <add path="*.rem" verb="*" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="False" />
12
13 <add path="*.soap" verb="*" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="False" />
14
15 <add path="*.asax" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
16
17 <add path="*.ascx" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
18
19 <add path="*.master" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
20
21 …… 22
23 <add path="*" verb="GET,HEAD,POST" type="System.Web.DefaultHttpHandler" validate="True" />
24
25 <add path="*" verb="*" type="System.Web.HttpMethodNotAllowedHandler" validate="True" />
26
27 </httpHandlers>
.Net Framework在處理Http請求時採用默認Handler,而若是要操控一個Http請求,就須要實現IHTTPHandler接口,而實現IHttpHandler接口的類就是通常處理程序。
1 // 摘要: 2
3 // 定義 ASP.NET 爲使用自定義 HTTP 處理程序同步處理 HTTP Web 請求而實現的協定。
4
5 public interface IHttpHandler 6
7 { 8
9 bool IsReusable { get; } 10
11 void ProcessRequest(HttpContext context); 12
13 }
該接口中包含一個屬性和一個方法,其中ProcessRequest方法中的代碼是處理請求的主要代碼。IsReusable屬性,該值指示其餘請求是否可使用IHttpHandler實例,也就是說後繼的Http請求是否是能夠繼續使用實現了該接口的類的實例,爲true時能夠,不然不能夠。下面是一個自定義的處理程序:
1 public class Handler1 : IHttpHandler 2 { 3 public void ProcessRequest(HttpContext context) 4 { 5 //處理請求的代碼
6 } 7 public bool IsReusable 8 { 9 get
10 { 11 return true; 12 } 13 } 14 }
建立一個自定義的HttpHandler後,爲了讓它可以處理某些HTTP請求,還須要將它註冊到web.config中:
1 <httpHandlers>
2
3 <add verb="*" path="*.jpg" type="Test_js.Handler1"/>
4
5 </httpHandlers>
path:指的是請求的文件名稱,可使用通配符擴大範圍,也能夠明確指定這個Handler僅用於處理某個特定的文件的請求。
verb:指的是請求此文件的方式,可使post或get,用*表明全部的訪問方式。
type:程序集.類名
IHttpFactory接口概述:
1 public interface IHttpHandlerFactory 2
3 { 4
5 IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated); 6
7 void ReleaseHandler(IHttpHandler handler); 8
9 }
GetHandler方法中的參數介紹:
context:System.Web.HttpContext 類的實例,它提供對用於爲 HTTP 請求提供服務的內部服務器對象(如 Request、Response、Session和 Server)的引用。
requestType:客戶端使用的 HTTP 數據傳輸方法(GET 或 POST)。
url:所請求資源的 System.Web.HttpRequest.RawUrl。
pathTranslated:所請求資源的 System.Web.HttpRequest.PhysicalApplicationPath。
該接口中定義了2個方法,GetHandler方法在請求開始的時候被調用,而ReleaseHandler在請求結束,全部的Handler都不在須要的時候被調用。
一個HandlerFactory能夠處理N個HttpHandler,何時該處理什麼HttpHandler就在這裏的處理邏輯中實現。
何時使用IHttpHandlerFactory:
一、在一個項目中須要使用不少IHttpHandler的時候,並且對這些IHttpHandler判斷都重複作一個一樣的前期處理。
二、從部署和鬆散耦合考慮,若是你的web application足夠大,你就要考慮在更換HttpHandler處理類的時候該不應去改動Web.config的配置,這種改動將會從新啓動整個app,對於一些系統而言這是不能夠隨便進行的。這個時候,統一一個入口的IHttpHandlerFactory很重要,這個入口相對不變,而IHttpHandler實現能夠經過外掛自定義的xml文件來實現鬆散耦合,運用一些反射什麼的就能夠實現了。
3、HttpModule是實現了IHttpModule接口的程序集,HttpModule的做用是與應用程序事件相關的。
1 public interface IHttpModule 2
3 { 4
5 void Dispose(); 6
7 void Init(HttpApplication context); 8
9 }
Init()方法:這個方法接受一個HttpApplication對象,HttpApplication表明了當前的應用程序,在這個方法中註冊對事件進行註冊。
Dispose():它能夠在進行垃圾回收以前進行一些清理工做。
經過在Http請求管道中註冊指望對應用程序事件做出反應的方法,在相應的事件觸發的時候,便會調用HttpModule註冊了的方法,實際的工做在這些方法中執行。
自定義的HttpModule須要咱們本身在web.config文件中對其進行註冊:
1 <system.webServer>
2 <modules>
3 <add name="MyModule" type="WebApplication1.ModuleDemo,WebApplication1"/>
4 </modules>
5 </system.webServer>
整個過程:
一、當站點第一個資源被訪問的時候,Asp.Net會建立HttpApplication類的實例,它表明着站點應用程序,同時會建立全部在Web.Config中註冊過的Module實例。
二、在建立Module實例的時候會調用Module的Init()方法。
三、在Init()方法內,對想要做出響應的HttpApplication暴露出的事件進行註冊。(僅僅進行方法的簡單註冊,實際的方法須要另寫)。
四、HttpApplication在其應用程序週期中觸發各種事件。
五、觸發事件的時候調用Module在其Init()方法中註冊過的方法