第十五节: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 : 原创博客请在转载时保留原文连接或在文章开头加上本人博客地址,不然保留追究法律责任的权利。
相关文章
相关标签/搜索