对Cookie和Session的理解

  相信很多搞BS开发的小伙伴,多多少少都会了解到 Cookie 和 Session 这两个对象,我们用到最多的地方,就要属登陆了,登陆之后,把用户信息 User 存放在Session里面,然后只要浏览器不关闭或手动退出,就可以直接保持登陆状态,随时获取的保存在Session里面的用户信息。

  我们知道浏览器请求是基于 Http协议的请求,它是无连接,无状态的,客户端请求一次,服务器就反馈一次,而且这一次请求和下一次请求 没有任何的关系,也就是说,服务器完全不知道连续的两次请求都是你发送的。

  Cookie是保存在客户端的,而Session是保存在服务器的,这是我们都知道的一个最基本的常识。那我们先认识一下Cookie。

直接上代码

1         public string SetCookie()
2         {
3 
4             HttpCookie myCookie = new HttpCookie("myCustomCookie", "abc");
5             myCookie.Expires = DateTime.Now.AddMinutes(1);
6             Response.Cookies.Add(myCookie);
7 
8             return "Cookie 设置成功";
9         }
View Code

Expires(过期时间)属性很重要,如果不设置,Cookie 会保存在浏览器内存中,关闭浏览器之后cookie就会被释放。如果过期时间大于当前时间,cookie就会保存在客户端的硬盘上面,而且在过期时间之前,每次请求都会带上该Cookie。如果过期时间小于或等于当前时间,就相当于删除该cookie。

  那么Session实现的原理是什么呐,我们写了一个方法来测试一下,

1         public string SetSession()
2         {
3             Session["loginUser"] = "mxj";
4             HttpContext.Session["loginPwd"] = "123";
5             HttpContext.Session.Timeout = 1;
6 
7 
8             return "Session 设置成功";
9         }
View Code

  我们访问这个方法,给Session设置了值,然后我们发现每次请求的时候,都会带一个ASP.NET_SessionId的Cookie。

其实Session功能就是基于这个ASP.NET_SessionId的Cookie来实现实,当我们用 Session["loginUser"] = "mxj"; 设置一个Session值的时候,我们可以理解为一个Key,Value 的字典容器,Key就是当前ASP.NET_SessionId的Cookie值 ,Value就是这个类型为System.Web.HttpSessionStateWrapper的Session对象,我们对Session的操作其实就是对这个类型为HttpSessionStateWrapper的一个实例来进行操作。所以,我们可以简单的理解为Session其实就是保存在服务内存里的以ASP.NET_SessionId为Key的字典的值的一个对象

  按照上面的理解,如果我们设置了Session的值,然后再把ASP.NET_SessionId的cookie清除掉,我们就访问不到Session的值,我们来验证一下,代码如下

 1     public string SetSession()
 2         {
 3             Session["loginUser"] = "mxj";
 4             HttpContext.Session["loginPwd"] = "123";
 5             HttpContext.Session.Timeout = 1;
 6 
 7 
 8             return "Session 设置成功";
 9         }
10 
11         public string GetSession()
12         {
13             StringBuilder sb = new StringBuilder();
14 
15             HttpSessionStateBase sessionStateBase = HttpContext.Session;
16             for (int i = 0; i < sessionStateBase.Count; i++)
17             {
18                 sb.Append(sessionStateBase.Keys[i] + "" + sessionStateBase[i] + "<br/>");
19             }  
20 
21             return sb.ToString();            
22         }
23 
24         public string ClearCookie()
25         {
26             HttpCookieCollection newCollection = new HttpCookieCollection();
27             HttpCookieCollection cookieCollection = Request.Cookies;
28             for (int i = 0; i < cookieCollection.Count; i++)
29             {
30                 cookieCollection[i].Expires = DateTime.Now.AddMinutes(-1);
31                 newCollection.Add(cookieCollection[i]);
32 
33                 //Response.SetCookie(cookieCollection[i]);
34             }
35 
36             for (int j = 0; j < newCollection.Count; j++)
37             {
38                 Response.Cookies.Add(newCollection[j]);
39             }
40 
41             return "Cookie Clear成功";
42         }
View Code

我们先执行方法SetSession,然后再执行方法GetSession,我们会得到Session的值

执行此方法时,我们一定要把发送此请求所用的cookie记录下来,后面用爬虫模拟请求的时候会用到

然后我们执行方法ClearCookie清除所有cookie,然后再执行方法GetSession去获取Session,没有任何的结果,(一片空白,无结果,就不截图了)。

那么服务器内存里对应这个ASP.NET_SessionId的key的value值是继续存在呐,还是被移除掉了呐?

我们写了一个简单的爬虫来验证结果,代码如下

  1         private void btnCatch_Click(object sender, EventArgs e)
  2         {
  3             var url = tbxUrl.Text;
  4             url = url.Trim();
  5 
  6             var cookie = tbxCookie.Text;
  7 
  8             var result = HttpHelper.DownloadUrl(url, cookie);
  9 
 10             tbxResult.Text = result;
 11         }
 12 
 13 
 14 
 15  public class HttpHelper
 16     {
 17         //private static Logger logger = new Logger(typeof(HttpHelper));
 18 
 19         /// <summary>
 20         /// 根据url下载内容  之前是GB2312
 21         /// </summary>
 22         /// <param name="url"></param>
 23         /// <returns></returns>
 24         public static string DownloadUrl(string url, string cookie = null)
 25         {
 26             return DownloadHtml(url, Encoding.UTF8, cookie);
 27         }
 28 
 29         //HttpClient--WebApi
 30 
 31         /// <summary>
 32         /// 下载html
 33         /// http://tool.sufeinet.com/HttpHelper.aspx
 34         /// HttpWebRequest功能比较丰富,WebClient使用比较简单
 35         /// </summary>
 36         /// <param name="url"></param>
 37         /// <returns></returns>
 38         public static string DownloadHtml(string url, Encoding encode, string cookie)
 39         {
 40             string html = string.Empty;
 41             try
 42             {
 43                 //https可以下载--
 44 
 45                 //ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) =>
 46                 //{
 47                 //    return true; //总是接受  
 48                 //});
 49                 //ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
 50 
 51                 HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest;//模拟请求
 52                 request.Timeout = 30 * 1000;//设置30s的超时
 53                 //request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36";
 54                 //request.UserAgent = "User - Agent:Mozilla / 5.0(iPhone; CPU iPhone OS 7_1_2 like Mac OS X) App leWebKit/ 537.51.2(KHTML, like Gecko) Version / 7.0 Mobile / 11D257 Safari / 9537.53";
 55 
 56                 request.ContentType = "text/html; charset=utf-8";// "text/html;charset=gbk";// 
 57                                                                  //request.Host = "search.yhd.com";
 58 
 59                 request.Headers.Add("Cookie", cookie);
 60 
 61                 //request.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
 62                 //request.Headers.Add("Accept-Encoding", "gzip, deflate, sdch");
 63                 //request.Headers.Add("Referer", "http://list.yhd.com/c0-0/b/a-s1-v0-p1-price-d0-f0-m1-rt0-pid-mid0-kiphone/");
 64 
 65                 //Encoding enc = Encoding.GetEncoding("GB2312"); // 如果是乱码就改成 utf-8 / GB2312
 66 
 67                 //如何自动读取cookie
 68                 //request.CookieContainer = new CookieContainer();//1 给请求准备个container
 69                 using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)//发起请求
 70                 {
 71                     if (response.StatusCode != HttpStatusCode.OK)
 72                     {
 73                         //logger.Warn(string.Format("抓取{0}地址返回失败,response.StatusCode为{1}", url, response.StatusCode));
 74                     }
 75                     else
 76                     {
 77                         try
 78                         {
 79                             //string sessionValue = response.Cookies["ASP.NET_SessionId"].Value;//2 读取cookie
 80                             StreamReader sr = new StreamReader(response.GetResponseStream(), encode);
 81                             html = sr.ReadToEnd();//读取数据
 82                             sr.Close();
 83                         }
 84                         catch (Exception ex)
 85                         {
 86                             //logger.Error(string.Format($"DownloadHtml抓取{url}失败"), ex);
 87                             html = null;
 88                         }
 89                     }
 90                 }
 91             }
 92             catch (System.Net.WebException ex)
 93             {
 94                 if (ex.Message.Equals("远程服务器返回错误: (306)。"))
 95                 {
 96                     //logger.Error("远程服务器返回错误: (306)。", ex);
 97                     html = null;
 98                 }
 99             }
100             catch (Exception ex)
101             {
102                 //logger.Error(string.Format("DownloadHtml抓取{0}出现异常", url), ex);
103                 html = null;
104             }
105             return html;
106         }
107     }
View Code

这是一个winform的程序,抓取结果如下

在服务器还没有释放Session值之前,我们还是可以通过ASP.NET_SessionId的Cookie获取到对应的Session值。

  那么Session在服务器内存会保存多久呐,

我们会有一个Timeout的属性来设置它的过期时间(分钟为单位),如果没有设置,就默认配置文件为准,IIS的默认Session释放时间好像是20分钟。

以上是本人自己摸索所得,有什么不正确的地方,欢迎提出意见。

猜你喜欢

转载自www.cnblogs.com/xiaoZhang521/p/11287773.html
今日推荐