深入学习客户端储存---cookie

HTTP cookie也被称作cook,最初用于在客户端会话信息,这个规范要求服务器在响应HTTP请求时,通过发送set-CookieHTTP头部包含会话信息.如下是包含这个头部的HTTP响应示例:
注意:CSDN博客就是使用这种模式,可以打开控制台>Network查看

在这里插入图片描述

这个HTTP响应示例设置了一个名为uuid_tt_dd,等号后面为值得cookie.名和值在发送时都会经过URL解码,浏览器会储存这些会话信息,并且在之后的每个请求中都会通过HTTP头部cookie再将它们发回服务器.比如:

在这里插入图片描述

这些发送回服务器的额外信息可用于唯一标识发送请求的客户端.

0.cookie的限制

  • cookie是与特定域绑定的.设置cookie后,它会被与请求一起发送到创建它的域.这个限制能保证cookie中存储的信息只对被认可的接受者开放,不被其他与访问.
  • 因为cookie存储在客户端机器上,所以保证它不会被恶意利用,浏览器会施加限制.同时,cookie也不会占用太多磁盘空间.

通常,只要遵守以下大致的限制,就不会再任何浏览器中碰到问题:

  • 不超过300个cookie;
  • 每个cookie不超过4096字节;
  • 每个域不超过20个cookie;
  • 每个域不超过81920字节;

每个域能设置的cookie总是也是受限的,但不同浏览器的限制不同.例如:

  • 最新版IE和Edge限制每个域不超过50个cookie;
  • 最新版Firefox限制每个域不超过150个cookie;
  • 最新版Opera限制每个域不超过180个cookie;
  • Safari和Chrome对每个域的cookie数没有硬性限制
  • 如果总数超过单个域上限,浏览器会删除之前设置的cookie.IEOpera会按照最近最少使用原则删除,为新cookie腾空间.Firefox好像会随机删除,因此为避免不确定的风险,最好不要超出限制.
  • 浏览器会限制cookie的大小,大多浏览器对cookie的限制是不超4096字节,为了跨浏览器兼容,最好不超过4095字节(上下一个字节误差).这个大小限制适用于一个域的所有cookie而非单个.

1.cookie的构成

在这里插入图片描述

cookie在浏览器中是由以下参数构成的:

  • 名称:唯一标识cookie的名称,必须经过URL编码,不分大小写,但最好区别大小写.
  • :存储在cookie的字符串,必须经过URL编码
  • :cookie有效的域,发送到这个域的所有请求都会包含对应的cookie.这个值可能包含子域(如www.wrox.com),也可以不包含(如:wrox.com表示对wrox.com的所有子域都有效).如果不明确设置,默认设置cookie的域.
  • 路径:请求URL中包含这个路径才会把cookie发送到服务器
  • 过期时间:表示什么时候删除cookie的时间戳(即什么时间不发送给服务器),默认会话结束删除所有cookie,可以指定删除时间,这个值是GMT格式,这样关闭浏览器也会留在用户机器上.将时间设置为过去的事件会删除cookie.
  • 安全标志:设置之后,只会使用SSL安全连接的情况下才会把cookie发送到服务器.例如,请求https://www,wrox.com会发送cookie,而请求http://www,wrox.com则不会.安全标志是cookie中惟一的非名/值对,只需一个secure就可以.

域、路径、过期时间和安全标志用于告诉浏览器什么时候在请求中包含cookie。这些参数并不会随便随请求发送给服务器,实际发送的只有cookie的名、值对。

2.JavaScript中的cookie

JavaScript中处理cookie比较麻烦,因为接口比较简单,只有BOMdocument.cookie属性.根据使用方法不同,该属性的表现迥异,要使用该属性获取值时,document.cookie返回包含页面中所有有效cookie的字符串(根据域、路径、过期时间和安全设置),以分号分隔,如下例子:

在这里插入图片描述

所有名和值都是URL编码的,因此必须使用decodeURIComponent()解码.

在这里插入图片描述

在设置值时,可以通过document.cookie属性设置新的cookie字符串.这个字符串在被解析后会添加到原有的cookie中.设置document.cookie不会覆盖之前存在的任何cookie,除非设置了已有的cookie.设置格式与set-Cookie头部的格式一样,在这些参数中只有名和值时必须的

在这里插入图片描述

在这里插入图片描述

这行代码会创建一个名为’name‘的会话cookie,值为’any’,这个cookie在每次客户端向服务器发送请求时都会被带上,在浏览器关闭时会被删除.虽然这样直接设置也可以,因为不需要在名称或值中编码任何字符,但最好还是使用 encodeURIComponent() 对名和值进行编码

在这里插入图片描述

要为创建的cookie指定额外的信息,只要像set-Cookie头部一样直接在后面追加相同的字符串即可

在这里插入图片描述

因为在JavaScript中读写cookie不是很直观,所以可以通过辅助函数来简化响应的操作,与cookie相关的基本操作有读、写和删除。这些在CookieUtil对象中表现如下:

class CookieUtil {
    // CookieUtil.get()方法用于取得给定名称的coookie值
    static get(name) {
        // 为此,需要在document.cookie返回的字符串查找是否存在后面加上等号
        let cookieName = `${encodeURIComponent("name")}=`,
            cookieStart = document.cookie.indexOf(cookieName),
            cookieValue = null;
        // 如果找到了再查找该位置后面的分号(便是该cookie的末尾)
        // 如果没有找到分号,说明这个cookie在字符串末尾
        // 因此字符串剩余部分都是cookie的值.取得cookie后解码返回
        //如果没有找到返回null
        if (cookieStart > -1) {
            let cookieEnd = document.cookie.indexOf(';', cookieStart);
            if (cookieEnd == -1) {
                cookieEnd = document.cookie.length
            }
            cookieValue = decodeURIComponent(document.cookie.substring(cookieStart
                + cookitName.length), cookieEnd)
        }
        return cookieValue
    }
    // CookieUtil.set()方法用于设置页面上的cookie,接收多个参数
    // 这些参数只有前两个是必需的
    //在方法内部使用了encodeURIComponent()对名和值进行编码,然后再依次检查
    static set(name, value, expires, path, domain, secure) {
        let cookieText = `${encodeURIComponent("name")}=${encodeURIComponent("value")}`
        // 如果expires参数是Date对象,则使用Date对象的toGMTString()
        // 方法添加一个expires选项来获得正确的日期格式
        if (expires instanceof Date) {
            cookieText += `; expires=${expires.toGMTString()}`
        }
        // 剩下的代码就是简单的追加cookie字符串,最终设置给document.cookie
        if (path) {
            cookieText += `;path=${path}`
        }
        if (domain) {
            cookieText += `;domain=${domain}`
        }
        if (secure) {
            cookieText += `;secure`
        }
        document.cookie = cookieText
    }
    // 没有直接删除已有cookie的方法,为此需要再次设置同名cookie(相同路径、
    // 域和安全选项),日期要选过去的时间
    // CookieUtil.unset()方法实现了这些处理.这个方法接收四个参数
    // 要删除的cookie名称,可选的路径,可选的域,可选的安全标志
    static unset(name, path, domain, secure) {
        // 这些参数会传给CookieUtil.unset(),将cookie值设置为空字符串
        // 过期日期设置为1970年1月1日(以0毫秒初始化的Date对象的值)
        CookieUtil.set(name, '', new Date(0), path, domain, secure)
    }
}
  • 可以像下面这样使用这些方法:
  • 设置cookie
CookieUtil.set('name','山竹回家了')
  • 读取cookie
 alerf(CookieUtil.get('name'))
  • 删除cookie
 CookieUtil.unset('name')
  • 设置路径/域/过期时间的cookie
CookieUtil.set('name', '山竹回家了','/books/projs/', 'www.wrox.com',
    new Date('january 1,2010'))
  • 删除刚刚设置的cookie
CookieUtil.unset('name', '/books/projs/', 'www.wrox.com')
  • 设置安全cookie
CookieUtil.set('name', '山竹回家了', null, null, null, true)

3.使用cookie的注意事项

  • 还有一种叫做HTTP-only的cookie.HTTP-only可以在浏览器设置,也可以在服务器设置,但只能在服务器上读取,这是因为JavaScript无法取得这种cookie的值.
  • 因为所有cookie都会座位请求头部由浏览器发送给服务器,所以在cookie中保存大量信息可能会被影响特定浏览器请求的性能.保存的cookie越大,请求完成的事件就越长.即使浏览器对cookie大小有限制,最好还是尽可能只通过cookie保存必要信息,以避免性能问题
  • 对cookie的限制及其特性决定了cookie并不是存储大量数据的理想方式,因此,有机会会再讲些其他客户端存储技术.

4.注意

不要在cookie中存储重要或敏感的信息,cookie数据不是保存在安全的环境中,因此任何人都可能获得,应避免把信用卡号或个人地址等信息保存在cookie中.

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值