当前位置: 首页 > 后端技术 > Node.js

深入理解浏览器存储——从cookies到WebStorage,IndexedDB

时间:2023-04-03 13:09:12 Node.js

前言随着移动网络的发展演进,我们现在除了手机上的原生Apps,还可以运行“WebApps”——随时准备使用,使用走开。一个优秀的WebApp甚至可以拥有媲美原生App的功能和体验。WebApp的出色性能部分归功于浏览器存储技术的改进。cookies中存储数据的功能已经难以满足发展的需要,逐渐被WebStorage和IndexedDB所取代。本文将介绍这几种存储方式的区别和优缺点。想阅读更多优质文章,请戳GitHub博客1.Cookie1的来源。CookieCookie的工作不是存储在本地,而是“保持状态”。因为HTTP协议是无状态的,HTTP协议本身并不保存请求和响应之间的通信状态。一般来说,服务器并不知道用户上次做了什么,这严重阻碍了交互式网络应用的实现。在典型的在线购物场景中,用户浏览多个页面并购买一盒饼干和两瓶饮料。在最后结账的时候,由于HTTP的无状态特性,如果没有额外的手段,服务器是不知道用户买了什么的,所以Cookie就诞生了。它是用来规避HTTP无状态的“额外”之一。服务器可以设置或读取Cookies中包含的信息,从而维持用户与服务器的会话状态。我们可以将cookie理解为存储在浏览器中的一个小文本文件,它附加在HTTP请求中,“飞”在浏览器和服务器之间。它可以携带用户信息,当服务器检查cookie时,可以得到客户端的状态。在刚刚的购物场景中,当用户购买了第一件商品时,服务器在向用户发送网页的同时,发送了一个cookie来记录该商品的信息。当用户访问另一个页面时,浏览器会将cookie发送给服务器,这样服务器就知道他之前买了什么。用户继续购买饮料,服务器在原有cookie中添加新的商品信息。结帐时,服务器读取发送的cookie。2、什么是cookie及其应用场景cookie是指一些网站为了识别用户身份而存储在用户本地终端上的数据(通常是加密的)。Cookie由服务器生成并由客户端维护和存储。通过cookie,服务端可以知道请求来自哪个客户端,进而维护客户端的状态。例如登录刷新后,请求头会在登录时在响应头中携带set-cookie,当web服务器收到请求时,也会读取出cookie的值,并且信息根据cookie值的内容,可以判断和恢复部分用户的状态。如上图所示,cookie以键值对的形式存在。典型的应用场景包括:记住密码,下次自动登录。购物车功能。记录用户浏览数据,推荐商品(广告)。三、cookies的原理及产生cookies的方式cookies的原理第一次访问网站时,浏览器发出请求,服务器响应请求后,会在响应头,并将cookie放入响应请求中。浏览器第二次发送请求时,会通过Cookie请求头向服务器发送Cookie信息,服务器会识别用户身份。另外cookie的过期时间、域、路径、有效期、适用站点都可以根据需要自定义。指定。cookie的生成方式主要有两种:生成方式一:http响应头中的set-cookie我们可以通过响应头中的Set-Cookie来指定要存储的cookie值。默认情况下,domain设置为cookie页面的主机名,我们也可以手动设置domain的值。设置Cookie:id=a3fWa;Expires=Wed,21Oct201807:28:00GMT;//设置cookie过期时间时可以指定具体的过期时间(Expires)或有效期(Max-Age),设置的日期和时间才相关给客户端,而不是服务器。生成方式二:可以在js中通过document.cookie读写cookies,并以键值对的形式显示。比如我们在掘金社区控制台输入如下三行代码,就可以在Chrome的应用面板中查看生成的cookie:document.cookie="userName=hello"document.cookie="gender=male"document.cookie='age=20;domain=.baidu.com'从上图我们可以得出结论,域名指定了哪些域名是可接受的Cookies。如果没有设置域,它会自动绑定到执行语句的当前域。如果设置为“.baidu.com”,则所有以“baidu.com”结尾的域名都可以访问该cookie,所以掘金社区无法读取第三段代码来存储cookie值。4、Cookie的缺陷Cookie不够大Cookie的大小被限制在4KB左右,对于复杂的存储需求是不够的。当cookie超过4KB时,就会面临被切掉的命运。因此,cookie只能用于访问少量信息。此外,许多浏览器也对站点的cookie数量有限制。这里注意:每个浏览器中每个name=cookies的值大约是4k,所以4k并不是一个域名下所有cookies共享的,而是一个name的大小。过多的cookie会带来巨大的性能浪费。Cookie跟在域名之后。同一个域名下的所有请求都会携带cookies。试想一下,如果我们此刻只是请求一张图片或者一个CSS文件,还得带着cookie跑来跑去(关键是不需要cookie中存储的信息),多么浪费时间和金钱。cookies虽然小,但是可以有很多请求。随着请求的叠加,这种不必要的cookie带来的开销将不堪设想。Cookie是用来维护用户信息的,所有在域名(domain)下的请求都会携带cookie,但是对于静态文件的请求,携带cookie信息是完全没有用的。网站域名单独解析。由于HTTP请求中的Cookie是明文传递的,除非使用HTTPS,否则安全性是个问题。5.Cookies与安全对于cookies,我们同样需要注意安全性。HttpOnly不支持读写,浏览器不允许脚本操作document.cookie来改变cookie,所以为了避免跨域脚本(XSS)攻击,标有HttpOnly的cookie不能通过JavaScript的Document.cookieAPI访问,它们应该只发送到服务器。如果包含服务器端Session信息的Cookie不想被客户端JavaScript脚本调用,那么就应该为它设置HttpOnly标志。设置Cookie:id=a3fWa;过期=2015年10月21日星期三07:28:00GMT;安全的;HttpOnly标记为Secure的Cookie只能通过HTTPS协议加密的请求发送到服务器。但即使设置了Secure标志,也不应通过cookie传输敏感信息,因为cookie本质上是不安全的,Secure标志无法提供真正的安全性。为了弥补cookies的局限性,让“专业的人做专业的事”,WebStorage出现了。HTML5中新增了一种本地存储方案----WebStorage,分为两类:sessionStorage和localStorage。这样,有了WebStorage,cookie就只能做它该做的事——作为客户端与服务器交互的通道,维护客户端的状态。二、LocalStorage1.LocalStorage的特点保存的数据长期存在。下次访问该网站时,该网页可以直接读取之前保存的数据。大小约为5M,仅在客户端使用。最好封装接口,不与服务器通信。基于以上特点,LocalStorage可以作为浏览器本地缓存方案,提高网页首屏的渲染速度(在根据第一次请求返回时,直接在本地存储一些不可变信息)。2.存储/读取数据localStorage中保存的数据以“键值对”的形式存在。也就是说,每一项数据都有一个键名和对应的值。所有数据都以文本格式保存。使用setItem方法存储数据。它接受两个参数,第一个是键名,第二个是保存的数据。localStorage.setItem("key","value");使用getItem方法读取数据。它只有一个参数,即键名。varvalueLocal=localStorage.getItem("key");具体步骤请看下面的例子:body>

3.LocalStorage在存储中的使用场景这方面没有特殊限制,理论上,Cookie不能做的,可以用简单的键值对访问的数据存储任务,都可以交给LocalStorage,这里给大家举个例子,考虑到LocalStorage的特点,一个是持久化,有时候我们更喜欢用它来存储一些内容稳定的资源,比如图片内容丰富的电商网站会用它来存储Base64格式的图片字符串:三、sessionStoragesessionStorage中保存的数据用于浏览器的一个session,当session结束(通常是窗口关闭),数据被清除;sessionStorage的特别之处在于即使是同一个域名下的两个页面,只要不是在同一个浏览器窗口打开,它们的sessionStorage内容是不能共享的;localStorage在所有同源窗口中共享;cookie也在同源的所有窗口中共享。SessionStorage的属性和方法除了存储期的长度外,与LocalStorage完全相同。1、sessionStorage的特点session级浏览器存储大小约为5M。它仅在客户端使用,不与服务器通信。接口包更好。基于以上特点,sessionStorage可以有效的维护表单信息。信息不会丢失。2、使用场景sessionStorage更适合存储其同步的生命周期和会话级信息。此信息仅适用于当前会话,在您开始新会话时需要相应更新或发布。比如微博的sessionStorage主要存储你本次session的浏览足迹:lasturl对应你上次访问的url地址,这个地址是instant的。当您切换URL时,它会相应更新。当你关闭页面的时候,真的没有必要保留它,释放它就可以了。此类数据最好用sessionStorage处理。3、sessionStorage、localStorage和cookie的区别是一个共同点:都是保存在浏览器端,都遵循同源策略。区别:在于生命周期和作用域的不同:localStorage只要在相同的协议、相同的主机名、相同的端口下,就可以读取/修改相同的localStorage数据。sessionStorage比localStorage更严格。除了协议、主机名、端口之外,还需要同一个窗口(即浏览器的标签页)的生命周期:localStorage是一个持久化的本地存储,存储在里面的数据是永远的。它不会过期,唯一让它消失的办法就是手动删除;而sessionStorage是临时本地存储,是会话级存储。当会话结束(页面关闭)时,存储的内容也被释放。WebStorage从定义到使用都是一件非常简单的事情。它以键值对的形式存储。这种模式有点类似于对象,但它甚至不是对象——它只能存储字符串。要获取对象,我们需要对字符串进行一轮解析。WebStorage毕竟是Cookie的扩展,只能用来存储少量的简单数据。当涉及到大规模、结构复杂的数据时,WebStorage就无能为力了。这时候就需要知道我们的终极大佬——IndexedDB了!第四,IndexedDBIndexedDB是一种用于客户端存储大量结构化数据(包括文件和blob)的低级API。API使用索引来实现此数据的高性能搜索。IndexedDB是一个运行在浏览器上的非关系型数据库。现在是数据库,不是5M、10M级别的。IndexedDB理论上没有存储限制(一般不小于250M)。它不仅可以存储字符串,还可以存储二进制数据。1.IndexedDB具有键值对存储的特点。IndexedDB内部使用一个对象库(objectstore)来存储数据。所有类型的数据都可以直接存储,包括JavaScript对象。在对象仓库中,数据以“键值对”的形式存储。每条数据记录都有对应的主键。主键是唯一的,不能重复,否则会报错。异步的IndexedDB操作不会锁定浏览器,用户仍然可以进行其他操作,这与LocalStorage的操作是同步的相反。异步设计是为了防止大量数据的读写,拖慢网页的性能。支持交易。IndexedDB支持事务,也就是说一系列的操作步骤只要有一步失败,整个事务就会被取消,数据库会回滚到事务发生前的状态,不会出现只有部分数据被重写。同源限制IndexedDB受同源限制,每个数据库对应创建的域名。网页只能访问自己域名下的数据库,不能访问跨域数据库。存储空间大IndexedDB的存储空间远大于LocalStorage,一般不低于250MB,甚至没有上限。支持二进制存储。IndexedDB不仅可以存储字符串,还可以存储二进制数据(ArrayBuffer对象和Blob对象)。2.IndexedDB的常用操作IndexedDB的大部分操作都不是我们通常的调用方式和返回结果的方式,而是请求-响应的方式。创建并打开IndexedDB----window.indexedDB.open("testDB")这个命令并没有返回一个DB对象的句柄,我们得到的是一个IDBOpenDBRequest对象,我们要得到的DB对象在它的result中property除了result,IDBOpenDBRequest接口还定义了几个重要的属性:onerror:请求失败的回调函数句柄onsuccess:请求成功的回调函数句柄onupgradeneeded:请求数据库版本变更句柄控制台获取一个IDBDatabase对象,即IndexedDB对象CloseIndexedDB----indexdb.close()functioncloseDB(db){db.close();}删除IndexedDB----window.indexedDB.deleteDatabase(indexdb)functiondeleteDB(name){indexedDB.deleteDatabase(name)}3、WebStorage、cookie和IndexedDB的区别从上表可以看出,cookie是没有建议长期存放。如果不需要大量的数据存储,可以使用localStorage和sessionStorage。对于变化不大的数据,尽量使用localStorage存储,否则可以使用sessionStorage存储。总结正是浏览器存储和缓存技术的出现和发展,给我们的前端应用带来了无限的机遇。近年来,基于存储和缓存技术的第三方库层出不穷,也衍生出了PWA等优秀的Web应用模型。总结一下本文的核心观点:cookies的工作不是本地存储,而是“保持状态”。WebStorage是HTML5专门为浏览器存储提供的一种数据存储机制。它不与服务器通信。IndexedDB用于客户端存储。海量结构化数据推荐好用的BUG监控工具Fundebug,欢迎免费试用!欢迎关注公众号:前端工匠,让我们一起见证你的成长!优质交流群微信公众号参考文章说清楚cookiesHTML5本地存储——IndexedDB(一:基本使用)详解Cookie、LocalStorage和SessionStorage前端性能优化原理与实践