第十五節:HttpContext五大核心對象的使用(Request、Response、Application、Server、Session)

 一. 基本認識javascript

 1. 簡介:HttpContext用於保持單個用戶、單個請求的數據,而且數據只在該請求期間保持;html

     也能夠用於保持須要在不一樣的HttpModules和HttpHandlers之間傳遞的值;java

     也能夠用於保持某個完整請求的相應信息。ajax

2. 五大核心對象包括:Response、Request、Application、Server、Sessionjson

3. 源碼分析:在MVC框架中HttpContext對象來源於一個HttpContextBase類的一個實例,該類中包括如下幾個重要屬性:(非MVC框架中有一個單獨HttpContext類)瀏覽器

   ①:HttpRequestBase Request服務器

   ②:HttpResponseBase Responsecookie

   ③:HttpApplicationStateBase Applicationsession

   ④:HttpServerUtilityBase Server多線程

   ⑤:HttpSessionStateBase Session

即所謂的五大核心對象,因此在MVC框架中一般能夠這麼用: HttpContext.Request、HttpContext.Response、HttpContext.Application、 HttpContext.Server、HttpContext.Session .

  但咱們也常常看到省略HttpContext對象,直接:Request、Response、Server、Session 來使用,隨意選中其中一個,點擊F12查看源碼可知,Controller類中也包含如下四個屬性:

  ①:HttpRequestBase Request

   ②:HttpResponseBase Response

   ③:HttpServerUtilityBase Server

   ④:HttpSessionStateBase Session

 

二. 逐個分析

1. Request對象

1. Request:接收處理客戶端發送過來的請求 (已完成)

 ①:HttpMethod屬性:獲取客戶端發送請求的類型

 ②:RawUrl屬性:獲取當前請求完整的URL

 ③:UrlReferrer屬性:獲取有關連接到當前 URL 的客戶端請求的 URL

 ④:Request["XX"]:獲取xx屬性值

2. 代碼測試

 1       //1.測試Request對象
 2             $("#btn1").click(function () {
 3                 $.ajax({
 4                     type: "Post",
 5                     url: "TestRequest",
 6                     data: {
 7                         "name": "123"
 8                     },
 9                     success: function (data) {
10                         if (data.status == "ok") {
11                             alert("測試經過");
12                             $("#s1").html(data.HttpMethod);
13                             $("#s2").html(data.RawUrl);
14                             $("#s3").html(data.UrlReferrer);
15                             $("#s4").html(data.name);
16                         }
17                         if (data == "error") {
18                             alert("測試未經過");
19                         }
20                     }
21                 });
22             });
 1         /// <summary>
 2         /// 測試Request對象相關
 3         /// </summary>
 4         /// <returns></returns>
 5         public ActionResult TestRequest()
 6         {
 7             var HttpMethod = Request.HttpMethod;
 8             var RawUrl = Request.RawUrl;
 9             var UrlReferrer = Request.UrlReferrer;
10             var name = Request["name"];
11             var data = new 
12             {
13                 status="ok",
14                 HttpMethod=HttpMethod,
15                 RawUrl= RawUrl,
16                 UrlReferrer= UrlReferrer,
17                 name= name
18             };
19             return Json(data);
20         } 

測試結果:

 

2. Server對象

1. Server:一個輔助類 (已完成)

 ①.HtmlEncode方法:將html編碼轉換成對應的字符串

 ②.HtmlDecode方法:將字符串轉換成Html編碼

 ③.MapPath方法:獲取該地址對應的物理路徑

 ④.UrlEncode方法:將url編碼轉換成對應的字符串

 ⑤.UrlDecode方法:將對應的字符串轉換成Url格式的編碼

2. 代碼測試

 1 //2.測試Server對象
 2             $("#btn2").click(function () {
 3                 $.ajax({
 4                     type: "Post",
 5                     url: "TestServer",
 6                     data: {
 7 
 8                     },
 9                     success: function (data) {
10                         if (data.status == "ok") {
11                             alert("測試經過");
12                             $("#s11").html(data.HtmlEncode);
13                             $("#s22").html(data.HtmlDecode);
14                             $("#s33").html(data.MapPath);
15                             $("#s44").html(data.UrlEncode);
16                             $("#s55").html(data.UrlDecode);
17                         }
18                         if (data == "error") {
19                             alert("測試未經過");
20                         }
21                     }
22                 });
23             });
 1     public ActionResult TestServer()
 2         {
 3             string HtmlEncode = Server.HtmlEncode("<p>積極向上</p>");
 4             string HtmlDecode = Server.HtmlDecode(HtmlEncode);
 5             string MapPath = Server.MapPath("/home/index");  //只能作物理文件的映射
 6             string UrlEncode = Server.UrlEncode("https://www.2345.com/");
 7             string UrlDecode = Server.UrlDecode(UrlEncode);
 8             var data = new
 9             {
10                 status = "ok",
11                 HtmlEncode = HtmlEncode,
12                 HtmlDecode = HtmlDecode,
13                 MapPath = MapPath,
14                 UrlEncode = UrlEncode,
15                 UrlDecode = UrlDecode
16             };
17             return Json(data);
18         }

測試結果:

3. Application對象

1. Application: 用於在ASP.NET 應用程序內的多個會話和請求之間共享信息(案例:單點登陸)

  ①. Lock方法:鎖定對象的訪問

  ②. unLock方法:取消鎖定對象的訪問

  ③. Add和Set方法:向集合中添加一個新對象

  ④. Application[]和Get方法:獲取對象的值

  ⑤. Remove、RemoveAt、RemoveAll方法:用來刪除對象

補充一個單一對話: HttpContextBase context.Item[""] ; 是指是一個IDictionary類,有Add、Clear、Contains、Remove等方法(不作測試)

2. 測試:

①. 用不一樣的瀏覽器打開Index頁面,模擬多線程多個會話,發現name2的值是相同的。

 

4. Response對象

1. Response:用戶服務器端將信息返回給客戶端

    ①.ContentType屬性:獲取或設置當前響應的 HTTP MIME 類型 (很是重要!),下面補充幾個經常使用的類型(多用於下載)

  a. Json格式: "application/json"

  b. JavaScript格式:"application/x-javascript"

  c. 普通文本格式:"text/plain"

  d. Html格式:"text/html"

  e. XML格式:"text/xml"

  f. Excel格式:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"

  g. gif圖片格式:"image/gif"

    ②.Redirect方法:用於站內跳轉或站點間的跳轉

    ③.Write方法:能夠將字符、字符串、字節等寫入到Http響應輸出流 (MVC中的Content方法就是基於該方法進行擴展的)

    ④.WriteFile和TransmitFile方法:將指定文件寫入到Http相應輸出流 (MVC中的FileResult就是基於該方法封裝的,簡化了下載流程)

  (原生的四種下載方法詳見:https://www.cnblogs.com/weixing/archive/2012/02/27/2369567.html (不作測試了))

2. 測試利用FileResult下載文件

 1        /// <summary>
 2         /// 測試下載文件
 3         /// </summary>
 4         /// <param name="type">1表明圖片  2表明Excel文件</param>
 5         /// <returns></returns>
 6         public ActionResult TestDownFile(string type)
 7         {
 8             if (type == "1")
 9             {
10                 //須要下載的文件在服務器上的物理路徑
11                 string path = Server.MapPath("/Content/imageHandle/pipe1.jpg");
12                 //須要下載的文件下載後保存到本地後的名字
13                 string fileName = DateTime.Now.ToString("yyyyMMddHHmmssffffff") + ".jpg";
14                 return File(path, "image/jpg", fileName);
15             }
16             if (type == "2")
17             {
18                 string path = Server.MapPath("/Content/myExcel/text.xlsx");
19                 string fileName = DateTime.Now.ToString("yyyyMMddHHmmssffffff") + ".xlsx";
20                 return File(path, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
21             }
22             return Content("");
23         } 
24     
1            //4. 測試下載文件
2             //4.1 下載圖片
3             $("#btn5").click(function () {         
4                 window.location.href = "TestDownFile?type=1";
5             });
6             //4.2 下載Excel
7             $("#btn6").click(function () {
8                 window.location.href = "TestDownFile?type=2";
9             });    

結果:

5. Session對象

 Session:存儲於服務器內存中key-value集合

(1).補充Cookie的概念:Cookie存儲於客戶端,經過瀏覽器的【Response Header】標頭下的Set-Cookie進行存儲,由瀏覽器進行創建、

保存、和到期刪除。Cookie默認的生命週期是瀏覽器的生命週期,瀏覽器關閉,cookie消失,固然也能夠顯式的設置Cookie的到期時間,瀏覽器會根據這個到期

時間,將Cookie存放到客戶端硬盤的。

注意:Cookie在瀏覽器能夠被看到,因此不適合存放敏感信息;Cookie能存儲的數據有限,最大4kb;Cookie是按照瀏覽器進行劃分的。

(2).Http的請求流程:

  ①:客戶端第一次訪問,沒有Cookie,沒有Session,服務器端會生成一個SessionId和一個空的Value,保存到服務器內存上。

  ②:客戶端第一次返回,經過瀏覽器的【Response Header】標頭下的Set-Cookie進行輸出。

  ③:客戶端第二次訪問,會帶上Cookie進行訪問,且Cookie中存放着SessionId,服務器端經過SessionMoudle解析獲得SessionId,獲取內存

  中存放的數據,而且知道剛纔你來過。

  ④:接下來在Session沒有過時和不關閉的瀏覽器的狀況下,每次訪問服務器端,都會帶着同一個SessionId進行訪問。

圖解:

 

(3).深刻剖析Session

  ①:同一個瀏覽器在不關閉的狀況下(且服務器端Session沒有過時),不管訪問幾回服務器端,SessionId都是相同的,由於每次請求都會帶着Cookie中存儲的SessionId的。

  ②:關閉瀏覽器,再次請求服務器,由於【Request Header】表頭中,沒有提交剛纔的SessionId,服務器會認爲這是一個新的請求,服務器會分配給你一個新的

SessionId,這就解釋了原SessionId並無過時爲何服務器會從新分配給你一個SessionId的緣由了。

  ③:同一個瀏覽器登陸狀態下,長時間沒有任何操做(Session默認過時時間爲20分鐘),再次操做的時候,雖然Cookie中帶着SessionId進行

訪問服務器端,可是原Session已經被服務器端給清除了,只保留SessionId,原存放到Session中的內容均爲null。

  ④:Session不能跨進程訪問,只能由當前會話的用戶訪問,由於SessionId是以Cookie的形式存放在訪問者的客戶端瀏覽器中。

  ⑤:在同一個會話中,Session是能夠跨頁面進行全局使用的。

  ⑥:服務器上的Session保存的是一個SessionId和一個Value,而Value是一個集合,該集合中存放着當前用戶的Key

(4).平常開發Session的侷限性

在咱們開發管理系統中,一般登陸後會把該用戶的權限放到Session中(如:放到Session["user"]中),這時候,在同一個瀏覽器中登陸admin帳戶,

會把a、b、c權限放到Session["user"]中,在不關閉該瀏覽器的狀況下,登陸admin2帳戶,這時候同一個瀏覽器請求的【Request Header】表頭中

的cookie存放的SessionId是相同的,因此服務器端會認爲是同一個會話,admin2帳戶的c,d權限會把原先的Session["user"]中的a、b、c權限覆蓋,

致使admin帳戶操做系統的時候,發現本身沒有 a、b、c權限,而是有c、d權限。

(如何解決這個問題呢?可使用NoSQL來替代Session)

(5).Session的聲明和銷燬

  ①:從寫入開始,若是該頁面一直沒有操做,默認20分鐘,服務器會把session銷燬,但SessionId仍是存在的。

  ②:手動經過Abandon的方式取消當前會話

  ③:刪除客戶端的Cookie,會致使服務器端從新分配給客戶端一個SessionId,其實服務器端的原Session並無消失

(6).總結:

客戶端向服務器發請求,若是請求頭中沒有帶SessionId,服務器會分配一個SessionId給客戶端,並存放在客戶端的Cookie中;

客戶端向服務器發送請求,若是cookie中有值,會帶着該值一塊兒發送到服務器,若是沒有,則不帶。

(7).補充Session的幾個經常使用方法

  ①:Session[]:用於設置或讀取Session的值

  ②:Timeout屬性:設置Session過時時間

  (補充經過配置文件的形式設置全局session過時:System.Web下添加 <sessionState mode="InProc" timeout="30"/> )

  InProc表示進程內;timeout表示多少分鐘後Session失效。

  ③:SessionID屬性:每一個會話的惟一標識符

  ④:Remove方法:從會話集合中刪除一項;Clear方法:從會話集合中刪除全部的鍵和值;Abandon方法:取消當前會話

MVC中的TempData就是基於Session實現的,可是TempData只能讀取一次

(8). 測試:

  ①:測試同一個瀏覽器,不關閉狀況下SessionId相同,且同一個key的數據會被後面覆蓋

  ②:測試服務器端Session過時後,SessionId還存在,Session中的值均爲Null(銷燬也是這個效果)

  ③:經過F12 瀏覽器驗證http流程,並查看【Response Header】和【Request Header】中何時又SessionId

  ④:手動刪除客戶端的Cookie,再次請求服務器,會從新分配新的SessionId

 先貼出來幾塊代碼:

 

a:打開該頁面,顯示SessionId和name的值,以下圖:

b:分析該頁面打開的請求,以下圖:印證Http請求第一次請求和第一次返回的請求流程

 

c. 點擊按鈕屢次,獲取SessionId和name的值,結果以下圖:SessionId和name的值都是相同的。(但刷新頁面,name值是變得,SessionID依舊不變)

 

d. 查看該按鈕對應的請求,以下圖:

 

e: 不關閉該瀏覽器的狀況下,從新在一個新的選項卡中打開Index頁面,SessionId沒有變,name從新賦值了。

 

f:回到第一次打開的頁面,從新點擊測試按鈕,獲取SessionId和name值,SessionId沒有變,可是name值被第二次打開的頁面的name值覆蓋了。(印證了管理系統中權限覆蓋的問題)

g:點擊銷燬Session,而後從新點擊測試按鈕,查看結果,SessionId依舊存在,可是Session的value集合變成null了(等待服務器session自動過時也是這種效果)

 

 

 

 

!

  • 做       者 : Yaopengfei(姚鵬飛)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 聲     明1 : 本人才疏學淺,用郭德綱的話說「我是一個小學生」,若有錯誤,歡迎討論,請勿謾罵^_^。
  • 聲     明2 : 原創博客請在轉載時保留原文連接或在文章開頭加上本人博客地址,不然保留追究法律責任的權利。
相關文章
相關標籤/搜索