zoukankan      html  css  js  c++  java
  • 对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分钟。

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

  • 相关阅读:
    No module named scrapy 成功安装scrapy,却无法import的解决方法
    linux装sqlite3
    linux python3 安装scrapy 后提示 -bash: scrapy: 未找到命令
    使用splash爬去JavaScript动态请求的内容
    python之auto鼠标/键盘事件
    python分割txt文件
    [WPF]使用WindowChrome自定义Window Style
    [UWP]浅谈按钮设计
    [UWP]用Shape做动画(2):使用与扩展PointAnimation
    [UWP]用Shape做动画
  • 原文地址:https://www.cnblogs.com/xiaoZhang521/p/11287773.html
Copyright © 2011-2022 走看看