标题:细说Cookie
取消只看楼主
wangnannan
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:87
帖 子:2545
专家分:9359
注 册:2007-11-3
结帖率:80.91%
 问题点数:0 回复次数:8 
细说Cookie
细说Cookie 说这话我就有点点狂了 我只说说我的理解 外加网上整理的 不足之处还请大家指教
1 现在网站可以没有cookie吗?
Cookie虽然是个很简单的东西 但它又是WEB开发中一个很重要的客户端数据来源 而且它可以实现扩展性很好的会话状态
所以我认为每个WEB开发人员都有必要对它有个清晰的认识

Cookie 概述
Cookie是什么?
Cookie 是一小段文本信息 伴随着用户请求和页面在 Web 服务器和浏览器之间传递 Cookie 包含每次用户访问站点时 Web 应用程序都可以读取的信息

为什么需要Cookie?
因为HTTP协议是无状态的 对于一个浏览器发出的多次请求 WEB服务器无法区分 是不是来源于同一个浏览器 所以 要额外的数据用于维护会话 ookie 正是这样的一段随HTTP请求一起被传递的额外数据

Cookie能做什么?
Cookie只是一段文本 以它只能保存字符串 且浏览器对它有大小限制以及 它会随着每次请求被发送到服务器 以应该保证它不要太大 cookie的内容也是明文保存的 些浏览器提供界面修改 所以  不适合保存重要的或者涉及隐私的内容

Cookie 的限制
大多数浏览器支持最大为 4096 字节的 Cookie 由于这限制了 Cookie 的大小 最好用 Cookie 来存储少量数据 或者存储用户 ID 之类的标识符 用户 ID 随后便可用于标识用户,以及从数据库或其他数据源中读取用户信息 浏览器还限制站点可以在用户计算机上存储的 Cookie 的数量 大多数浏览器只允许每个站点存储 20 个 Cookie;如果试图存储更多 Cookie 则最旧的 Cookie 便会被丢弃 有些浏览器还会对它们将接受的来自所有站点的 Cookie 总数作出绝对限制 通常为 300 个

Cookie的写、读过程
哈哈 这个不用多说了 大家心知肚明 来一段DEMO
中,读写Cookie是通过使用HttpCookie类来完成的,它的定义如下:
程序代码:
public sealed class HttpCookie
{
    // 获取或设置将此 Cookie 与其关联的域。默认值为当前域。
    public string Domain { get; set; }
    // 获取或设置此 Cookie 的过期日期和时间(在客户端)。
    public DateTime Expires { get; set; }
    // 获取一个值,通过该值指示 Cookie 是否具有子键。
    public bool HasKeys { get; }
    // 获取或设置一个值,该值指定 Cookie 是否可通过客户端脚本访问。
    // 如果 Cookie 具有 HttpOnly 属性且不能通过客户端脚本访问,则为 true;否则为 false。默认为 false。
    public bool HttpOnly { get; set; }
    // 获取或设置 Cookie 的名称。
    public string Name { get; set; }
    // 获取或设置要与当前 Cookie 一起传输的虚拟路径。默认值为当前请求的路径。
    public string Path { get; set; }
    // 获取或设置一个值,该值指示是否使用安全套接字层 (SSL)(即仅通过 HTTPS)传输 Cookie。
    public bool Secure { get; set; }
    // 获取或设置单个 Cookie 值。默认值为空引用。
    public string Value { get; set; }
    // 获取单个 Cookie 对象所包含的键值对的集合。
    public NameValueCollection Values { get; }
    // 获取 System.Web.HttpCookie.Values 属性的快捷方式。
    public string this[string key] { get; set; }
}
Cookie写入浏览器的过程:我们可以使用如下代码在项目中写一个Cookie 并发送到客户端的浏览器(为了简单我没有设置其它属性)。
HttpCookie cookie = new HttpCookie("MyCookieName", "string value");
Response.Cookies.Add(cookie);

写到这里我想很多人都写过类似的代码,但是,大家有没有想过:Cookie最后是如何发送到客户端的呢?
这里引入Fiddler Fiddler可是个好东西啊 破站 入侵 POST数据 离不开这个 是居家旅行 杀站越货必备之物


搜索更多相关主题的帖子: 浏览器 应用程序 会话状态 cookie Cookie 
2015-06-11 14:18
wangnannan
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:87
帖 子:2545
专家分:9359
注 册:2007-11-3
得分:0 
从上图,您应该能发现,我们在服务端写的Cookie,最后其实是通过HTTP的响应头这种途径发送到客户端的。每一个写入动作, 都会产生一个【Set-Cookie】的响应头。 这里很重要 例如要分析某个网站...你懂的
 浏览器正是在每次获取请求的响应后,检查这些头来接收Cookie的。

获取Cookie的过程:我们可以使用如下代码在项目中读取一个Cookie
程序代码:
HttpCookie cookie = Request.Cookies["MyCookieName"];
if( cookie != null )
    labCookie1.Text = cookie.Value;
else
    labCookie1.Text = "未定义";

代码同样也很简单,还是类似的问题:大家有没有想过,Cookie是如何传到服务端的呢?我们还是继续使用Fiddler来寻找答案吧。

出来混,谁不都要拼命的嘛。 。拼不赢?那就看谁倒霉了。 。有机会也要看谁下手快,快的就能赢,慢。 。狗屎你都抢不到。 。还说什么拼命?
2015-06-11 14:20
wangnannan
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:87
帖 子:2545
专家分:9359
注 册:2007-11-3
得分:0 
从图片中,我们可以发现,Cookie是放在请求头中,发送到服务端的。如果你一直刷新页面,就能发现, 每次HTTP请求,Cookie都会被发送。当然了,浏览器也不是发送它所接收到的所有Cookie,它会检查当前要请求的域名以及目录, 只要这二项目与Cookie对应的Domain和Path匹配,才会发送。对于Domain则是按照尾部匹配的原则进行的。
 所以,我在访问 时,浏览器并不会将我在浏览 www. 所接收到的 Cookie 发出去。
除Cookie:其实就是在写Cookie时,设置Expires为一个【早于现在时间的时间】。也就是:设置此Cookie已经过期, 浏览器接收到这个Cookie时,便会删除它们。
HttpCookie cookie = new HttpCookie("MyCookieName", null);
cookie.Expires = new DateTime(1900, 1, 1);
Response.Cookies.Add(cookie);


出来混,谁不都要拼命的嘛。 。拼不赢?那就看谁倒霉了。 。有机会也要看谁下手快,快的就能赢,慢。 。狗屎你都抢不到。 。还说什么拼命?
2015-06-11 14:20
wangnannan
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:87
帖 子:2545
专家分:9359
注 册:2007-11-3
得分:0 
OK 以上大家肯定都知道了 你都知道了 还说这些干什么 是的 我自己都觉得没啥可说的了 下边来点干货

出来混,谁不都要拼命的嘛。 。拼不赢?那就看谁倒霉了。 。有机会也要看谁下手快,快的就能赢,慢。 。狗屎你都抢不到。 。还说什么拼命?
2015-06-11 14:21
wangnannan
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:87
帖 子:2545
专家分:9359
注 册:2007-11-3
得分:0 
使用Cookie保存复杂对象
我们平时可能希望将更复杂的【自定义类型】通过Cookie来保存, 那么又该如何操作呢?对于这个问题,我们定义一个类型来看看如何处理。
程序代码:
public class DisplaySettings
{
    public int Style;

    public int Size;
   
    public override string ToString()
    {
        return string.Format("Style = {0}, Size = {1}", this.Style, this.Size);
    }   
}
上面的代码,我定义一个类型,用于保存用户在浏览页面时的显示设置。接下来,我将介绍二种方法在Cookie中保存并读取它们。
方法-1,经典做法。(注意前面给出的HttpCookie定义代码中的最后二个成员)
程序代码:
private void WriteCookie_2a()
{
    DisplaySettings setting = new DisplaySettings { Style = 1, Size = 24 };

    HttpCookie cookie = new HttpCookie("DisplaySettings1");
    cookie["Style"] = setting.Style.ToString();
    cookie["Size"] = setting.Size.ToString();

    Response.Cookies.Add(cookie);
}

private void ReadCookie_2a()
{
    HttpCookie cookie = Request.Cookies["DisplaySettings1"];
    if( cookie == null )
        labDisplaySettings1.Text = "未定义";
    else {
        DisplaySettings setting = new DisplaySettings();
        setting.Style = cookie["Style"].TryToInt();
        setting.Size = cookie["Size"].TryToInt();
        labDisplaySettings1.Text = setting.ToString();
    }
}




出来混,谁不都要拼命的嘛。 。拼不赢?那就看谁倒霉了。 。有机会也要看谁下手快,快的就能赢,慢。 。狗屎你都抢不到。 。还说什么拼命?
2015-06-11 14:22
wangnannan
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:87
帖 子:2545
专家分:9359
注 册:2007-11-3
得分:0 
方法-2,将对象JSON序列化为字符串。
程序代码:
private void WriteCookie_2b()
{
    DisplaySettings setting = new DisplaySettings { Style = 2, Size = 48 };

    HttpCookie cookie = new HttpCookie("DisplaySettings2", setting.ToJson());
    Response.Cookies.Add(cookie);
}

private void ReadCookie_2b()
{
    HttpCookie cookie = Request.Cookies["DisplaySettings2"];
    if( cookie == null )
        labDisplaySettings2.Text = "未定义";
    else {
        DisplaySettings setting = cookie.Value.FromJson<DisplaySettings>();
        labDisplaySettings2.Text = setting.ToString();
    }
}



出来混,谁不都要拼命的嘛。 。拼不赢?那就看谁倒霉了。 。有机会也要看谁下手快,快的就能赢,慢。 。狗屎你都抢不到。 。还说什么拼命?
2015-06-11 14:23
wangnannan
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:87
帖 子:2545
专家分:9359
注 册:2007-11-3
得分:0 
程序代码:
/// <summary>
/// 将一个对象序列化成 JSON 格式字符串
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static string ToJson(this object obj)
{
    if( obj == null )
        return string.Empty;

    JavaScriptSerializer jss = new JavaScriptSerializer();
    return jss.Serialize(obj);
}

/// <summary>
/// 从JSON字符串中反序列化对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="cookie"></param>
/// <returns></returns>
public static T FromJson<T>(this string cookie)
{
    if( string.IsNullOrEmpty(cookie) )
        return default(T);

    JavaScriptSerializer jss = new JavaScriptSerializer();
    return jss.Deserialize<T>(cookie);
}

出来混,谁不都要拼命的嘛。 。拼不赢?那就看谁倒霉了。 。有机会也要看谁下手快,快的就能赢,慢。 。狗屎你都抢不到。 。还说什么拼命?
2015-06-11 14:23
wangnannan
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:87
帖 子:2545
专家分:9359
注 册:2007-11-3
得分:0 
对于这二种方法,我个人更喜欢后者,因为它具有更好扩展性:如果类型增加了成员,不需要修改读写Cookie的代码。
 不过,这种方式产生的有些字符,比如【双引号】,极少数浏览器(Opera)不支持,所以需要做UrlEncode或者Base64编码处理。
 同理,对于第一种方法,遇到Value有【双引号】时,我们同样需要做UrlEncode或者Base64编码处理。

出来混,谁不都要拼命的嘛。 。拼不赢?那就看谁倒霉了。 。有机会也要看谁下手快,快的就能赢,慢。 。狗屎你都抢不到。 。还说什么拼命?
2015-06-11 14:24
wangnannan
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:87
帖 子:2545
专家分:9359
注 册:2007-11-3
得分:0 
没说完呢 留个空改天再说

出来混,谁不都要拼命的嘛。 。拼不赢?那就看谁倒霉了。 。有机会也要看谁下手快,快的就能赢,慢。 。狗屎你都抢不到。 。还说什么拼命?
2015-06-11 14:24



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-446476-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.256224 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved