cookie在2019

775 阅读8分钟

一、引子

自从H5的sessionStoragelocalStorage出现后,cookie的就业环境越来越艰难了。 理性的分析一波,cookie为啥就业机会越来越少,以及还有没有用武之地。 本篇重点讲述浏览器cookie。

二、 cookie是啥

cookie 是存储于访问者的计算机中的变量。每当同一台计算机通过浏览器请求某个页面时,就会发送这个 cookie。你可以使用 JavaScript 来创建和取回 cookie 的值。

关于cookie的分类大体可以定义两种:

1. HTTP cookie(网络Cookie)

HTTP cookie 一个HTTP cookie的(网络Cookie,浏览器cookie)是一小片数据的一个服务器发送到用户的网络浏览器。浏览器可以存储它并将其与下一个请求一起发送回同一服务器。通常情况下,它用于判断两个请求是否来自同一个浏览器 - 例如,保持用户登录。它记住无状态 HTTP协议的有状态信息。

来源MDN

总结: 在http请求中发送过来的cookie, 能够直接在浏览器存储一些希望记录的状态或内容。

2. Document.cookie(浏览器cookie)

可以使用Document.cookie属性通过JavaScript创建新的cookie ,如果HttpOnly没有设置标志,也可以从JavaScript访问现有的cookie。

**总结:**通过JavaScript对浏览器cookie进行增删改查操作。

三、 为什么需要浏览器缓存(cookie)

cookie翻译过来是“饼干”的意思,cookie在网络应用中到处存在. 由于http是无状态的协议,一旦客户端和服务器的数据交换完毕,就会断开连接,再次请求,会重新连接,这就说明服务器单从网络连接上是没有办法知道用户身份。因此每次新的用户请求时,给它颁发一个身份状态,下次访问,必须带上唯一身份状态,服务器根据不同状态,针对不同用户,做出不同的响应。

**总结:**http分辨不出当前客户端的状态,cookie就是存储在浏览器机器上的纯文本字符串,储存内容或状态信息,弥补http协议无状态的问题。

四、cookie在哪儿、怎么用?

栗子:

        /**
         * @params  cookie对应全部字段内容
         * @name 必需。规定 cookie 的名称。
         * @value 必需。规定 cookie 的值。
         * @expire 可选。规定 cookie 的有效期(默认即临时会话, 浏览器关闭即失效)。
         * @path 可选。规定 cookie 的服务器路径。
         * @domain 可选。规定 cookie 的域名。
         * @secure 可选。规定是否通过安全的 HTTPS 连接来传输 cookie。
         */
        document.cookie = 'userName=test123456';
        document.cookie = 'userId=' + window.escape('45456da4344/*-+w2/,;3d1a3') + 'expires=' + new Date();
        console.log(document.cookie); 
        // userName=test123456; userId=45456da4344/*-+w2/%2C%3B3d1a3expires=Tue Mar 26 2019 16:54:41 GMT+0800 (中国标准时间)

image

*注意1:*在cookie 的名或值中不能使用;,=空格、。key值可控,但value值是不确定的,需要escape()方法转为十六进制,此种方案还可以避免中文乱码的出现,解码时要用unescape();

*注意2:*获取指定的cookie值,如userName需要处理字符串获取;

*注意3:*删除cookie值的方法是把有效时间修改为过去时间;

*注意4:*Chrome 浏览器无法设置本地静态cookie, 需要模拟在线环境;

五、 H5之后cookie的就业环境

  • H5新增了sessionStoragelocalStorage两种浏览器缓存,一种是会话级,一种硬盘级;他们的行业竞争力到底多强。 简单了解一下他们:

    1. localStoragesessionStorage都是用来存储客户端临时信息的对象,存储在服务端,量大。附件1

    2. 他们均只能存储字符串类型的对象(虽然规范中可以存储其他原生类型的对象,但是目前为止没有浏览器对其进行实现)。

    3. localStorage生命周期是永久,这意味着除非手动清除localStorage信息,否则这些信息将永远存在。

    4. sessionStorage生命周期为当前窗口或标签页,一旦窗口或标签页被永久关闭了,那么所有通过sessionStorage存储的数据也就被清空了。

    5. 不同浏览器无法共享localStoragesessionStorage中的信息。相同浏览器的不同页面间可以共享相同的localStorage(页面属于相同域名和端口),但是不同页面或标签页间无法共享sessionStorage的信息。这里需要注意的是,页面及标签页仅指顶级窗口,如果一个标签页包含多个iframe标签且他们属于同源页面,那么他们之间是可以共享sessionStorage的。

    6. 可以通过setItem()、getItem()、removeItem()、clear()、key()、valueOf()方法进行增删改查;

    7. 可以通过事件storage进行监听。

简单来说,H5的缓存使用简单粗暴,存储服务端相对安全,容量和内容足够大,能够对应不同情况,完爆同行cookie,cookie凭啥在挣扎。

  • cookie尚未失业的原因:

    1. 如果禁用cookie权限,那么sessionStorage无法使用,原因在于sessionStorage仍然是基于sessionId判断对应数据,只不过是存在了服务端;(你大爷还是你大爷);

    2. 通过HTTP-cookie,可以使用PHP、Java等服务端语言操作cookie内容,并且能够设置HttpOnly防止客户端修改(说不安全的,逞强的说在secure属性下,"我还有https");

    3. cookie在与服务器通信时会附在Request Headers中发送到服务端,但H5缓存需要自己来根据需求封装;

    4. 跨页面缓存,session能够应用在单页面项目中,但对于跨页面(跨标签页)的项目有些力不从心,而localStorage虽然能够完成跨页面,但是需要手动删除,也需要额外处理;(粗糙的栗子附2)

  • cookie再就业会不会第二春: 先上结论,浏览器缓存中,H5正在逐步取代cookie,也建议使用H5的Web Storage;

    1. 抛开H5的优势不说,抛开安全性不谈,cookie的跨页面缓存虽然能够解决一定问题,但是并非无可替代,也正是因为跨页面缓存,会话级cookie是建立与整个浏览器进程的,现在的大部分浏览器即使在退出后进程仍然没有关闭,所以导致session Cookie的会话级存储被超预期的延长了,例如PC端的chrome浏览器,或手机端微信浏览器,需要特别注意。

    2. 关于cookie无法写入的问题

      • 在a.com写b.com的cookie无法写入;

      • 非https的请求但加入了secure参数的cookie无法写入;

      • 在Chrome浏览器下,a.com中缓存cookieuser,设置secure与domain=.erp.com时,b.com写入userdomain=.erp.com中cookie无法写入 解释:其实是Chrome的一种保护措施(Safari,Firefox 随便写),如果不存在这种保护措施,在b.com发起请求时,cookie会变成user=cookie_from_a_erp_com;user=cookie_from_b_erp_com;保护措施下,会默认读取同名中的第一个cookie发送。也就是在b.com发送请求时扔发送a.com的user。(前提是非要头铁的用同名cookie且设置secure)

总结:

cookie已经不适合作为唯一身份标识应用于项目中,但其特殊的优势在特定需求或接受/保存非敏感信息跨页面通信、获取服务端特定状态时,往往能收获不错的效果。因此,虽然提倡使用H5的Web Storage,但是灵活的应用cookie或许也是解决问题不错的思路。

补充:

  • 如何判断浏览器是否禁用了cookie
window.navigator.cookieEnabled
// 如果浏览器启用了cookie,该属性值为true。如果禁用了cookie,则值为false
  • js对特殊字符/中文转码方法

    escape()除了 ASCII 字母、数字和特定的符号外,对传进来的字符串全部进行转义编码,因此如果想对URL编码,最好不要使用此方法。而encodeURI() 用于编码整个URI,因为URI中的合法字符都不会被编码转换。encodeURIComponent方法在编码单个URIComponent(指请求参 数)应当是最常用的,它可以讲参数中的中文、特殊字符进行转义,而不会影响整个URL。

附1

IE 9          > 4999995 + 5 = 5000000
firefox 22.0 > 5242875 + 5 = 5242880
chrome  28.0  > 2621435 + 5 = 2621440
safari  5.1   > 2621435 + 5 = 2621440
opera   12.15 > 5M (超出则会弹出允许请求更多空间的对话框)

附2:

// 登录页面添加缓存
        window.document.cookie = 'userName=cookie';
        window.sessionStorage.setItem('userName', 'session');
        window.localStorage.setItem('userName', 'local');


// check页跨页面js获取缓存
        this.cookieVal = document.cookie.split('=')[1];
        this.sessionVal = window.sessionStorage.getItem('userName');
        this.localVal = window.localStorage.getItem('userName');


// check页跨页面html查看
        <p>我是cookie值: {{cookieVal || '空'}}</p>
        <p>我是session值: {{sessionVal || '空'}}</p>
        <p>我是local值: {{localVal || '空'}}</p>

image

引用:

  1. mp.weixin.qq.com/s/adz4MyFvT…

  2. mp.weixin.qq.com/s/RrFhVB2Hd…