相信很多搞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 }
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 }
我们访问这个方法,给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 }
我们先执行方法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 }
这是一个winform的程序,抓取结果如下
在服务器还没有释放Session值之前,我们还是可以通过ASP.NET_SessionId的Cookie获取到对应的Session值。
那么Session在服务器内存会保存多久呐,
我们会有一个Timeout的属性来设置它的过期时间(分钟为单位),如果没有设置,就默认配置文件为准,IIS的默认Session释放时间好像是20分钟。
以上是本人自己摸索所得,有什么不正确的地方,欢迎提出意见。
原文地址:https://www.cnblogs.com/xiaoZhang521/p/11287773.html