一、前言
web 前端技术日新月异,对于浏览器的存储来说,cookie 存储数据的功能已经很难满足开发所需,逐渐被 WebStorage 所取代,本文主要介绍 Cookie,WebStorage 和 IndexDB 之间差异。
二、Cookie
1.Cookie 的来源
因为 HTTP 协议是无状态的,HTTP 协议自身不对请求和响应之间的通信状态进行保存,通俗来说,服务器不知道用户上一次做了什么,这严重阻碍了交互式 Web 应用程序的实现。在典型的网上购物场景中,用户浏览了几个页面,买了一盒饼干和两瓶饮料。最后结帐时,由于 HTTP 的无状态性,不通过额外的手段,服务器并不知道用户到底买了什么,于是就诞生了 Cookie。它就是用来绕开 HTTP 的无状态性的“额外手段”之一。服务器可以设置或读取 Cookies 中包含信息,借此维护用户跟服务器会话中的状态。在刚才的购物场景中,当用户选购了第一项商品,服务器在向用户发送网页的同时,还发送了一段 Cookie,记录着那项商品的信息。当用户访问另一个页面,浏览器会把 Cookie 发送给服务器,于是服务器知道他之前选购了什么。用户继续选购饮料,服务器就在原来那段 Cookie 里追加新的商品信息。结帐时,服务器读取发送来的 Cookie 就行了。
2. 什么是 Cookie
Cookie 指某些网站为了辨别用户身份而储存在用户本地终端上的数据(通常经过加密)。cookie 是服务端生成,客户端进行维护和存储。通过 cookie, 可以让服务器知道请求是来源哪个客户端,就可以进行客户端状态的维护,比如登陆后刷新,就会请求头就会携带登陆时 response header 中的 set-cookie,Web 服务器接到请求时也能读出 cookie 的值,根据 cookie 值的内容就可以判断和恢复一些用户的信息状态。
3.Cookie 的特点
可以用于浏览器端和服务器端之间的交互,cookie 的数据会自动的传递到服务器,服务器端也可以写 cookie 到客户端。
客户端自身数据的存储,需要设置过期时间 expire。设置的 cookie 过期时间之前一直有效,即使窗口或浏览器关闭。若不设置过期时间,则表示这个 cookie 的生命期为浏览器会话期间,关闭浏览器窗口,cookie 就消失。
4.Cookie 的生成方式
生成方式一:http response header 中的 set-cookie 生成方式二:js 中可以通过 document.cookie 可以读写 cookie// 以键值对的形式展示
例如我们在简书控制台输入,以下两句代码,便可以在 ”Application” 查看生成的 cookie
<script>
document.cookie=”userName=hello”
document.cookie=”gender=male”
</script>
5.Cookie 的缺陷
cookie 会被附加在每个 HTTP 请求中,在 HttpRequest 和 HttpResponse 的 header 中都是要被传输的,所以无形中增加了一些不必要的流量损失。
cookie 是用来维护用户信息的,而域名 (domain) 下所有请求都会携带 cookie,但对于静态文件的请求,携带 cookie 信息根本没有用,此时可以通过 cdn(存储静态文件的)的域名和主站的域名分开来解决。
由于在 HTTP 请求中的 Cookie 是明文传递的,所以安全性成问题,除非用 HTTPS。
可以使用 HttpOnly 提升 Cookie 安全性。httponly 不支持读写,浏览器不允许脚本操作 document.cookie 去更改 cookie,一般情况下都应该设置这个为 true,这样可以避免被 XSS 攻击拿到 cookie。
Cookie 的大小限制在 4KB 左右,对于复杂的存储需求来说是不够用的。很多浏览器都限制一个站点的 cookie 个数也是有限制的。
这里需注意:各浏览器的 cookie 每一个 name=value 的 value 值大概在 4k,所以 4k 并不是一个域名下所有的 cookie 共享的, 而是一个 name 的大小。
基于 Cookie 存储数据功能有所欠缺,HTML5 中新增了本地存储的解决方案 —-WebStorage,它分成两类:sessionStorage 和 localStorage。这样有了 WebStorage 后,cookie 能只做它应该做的事情了——作为客户端与服务器交互的通道,保持客户端状态。
三、LocalStorage
1.LocalStorage 的特点
保存的数据长期存在,下一次访问该网站的时候,网页可以直接读取以前保存的数据。
大小为 5M 左右
仅在客户端使用,不和服务端进行通信
接口封装较好
基于上面的特点,LocalStorage 可以作为浏览器本地缓存方案,用来提升网页首屏渲染速度(根据第一请求返回时,将一些不变信息直接存储在本地)。
2. 存入 / 读取数据
localStorage 保存的数据,以“键值对”的形式存在。也就是说,每一项数据都有一个键名和对应的值。所有的数据都是以文本格式保存。存入数据使用 setItem 方法。它接受两个参数,第一个是键名,第二个是保存的数据。localStorage.setItem(“key”,”value”); 读取数据使用 getItem 方法。它只有一个参数,就是键名。var valueLocal = localStorage.getItem(“key”); 具体步骤,请看下面的例子:
<script>
if(window.localStorage){
localStorage.setItem(’name’,’world’)
localStorage.setItem(“gender’,’famale’)
}
</script>
<body>
<div id=”name”></div>
<div id=”gender”></div>
<script>
var name=localStorage.getItem(’name’)
var gender=localStorage.getItem(’gender’)
document.getElementById(’name’).innerHTML=name
document.getElementById(’gender’).innerHTML=gender
</script>
</body>
四、SessionStorage
sessionStorage 保存的数据用于浏览器的一次会话,当会话结束(通常是该窗口关闭),数据被清空;sessionStorage 不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie 也是在所有同源窗口中都是共享的。除了保存期限的长短不同,SessionStorage 的属性和方法与 LocalStorage 完全一样。
1.SessionStorage 的特点
会话级别的浏览器存储
大小为 5M 左右
仅在客户端使用,不和服务端进行通信
接口封装较好
基于上面的特点,SessionStorage 可以有效对表单信息进行维护,比如刷新时,表单信息不丢失。
2.sessionStorage、localStorage 和 cookie 之间的区别
共同点:都是保存在浏览器端,且同源的。
不同点如下:
五、IndexedDB
Web Storage 使用简单字符串键值对在本地存储数据,方便灵活,但是对于大量结构化数据存储力不从心,IndexedDB 是为了能够在客户端存储大量的结构化数据,并且使用索引高效检索的 API。
1.IndexedDB 的特点
IndexedDB 是一种低级 API,用于客户端存储大量结构化数据。该 API 使用索引来实现对该数据的高性能搜索。
为应用创建离线版本
2.IndexedDB 的常见操作
在 IndexedDB 大部分操作并不是我们常用的调用方法,返回结果的模式,而是请求——响应的模式①建立打开 indexdb —-window.indexedDB.open(“testDB”)这条指令并不会返回一个 DB 对象的句柄,我们得到的是一个 IDBOpenDBRequest 对象,而我们希望得到的 DB 对象在其 result 属性中
除了 result,IDBOpenDBRequest 接口定义了几个重要属性 onerror: 请求失败的回调函数句柄 onsuccess: 请求成功的回调函数句柄 onupgradeneeded: 请求数据库版本变化句柄
<script>
function openDB(name){
var request=window.indexedDB.open(name)// 建立打开 indexdb
request.onerror=function (e){
console.log(’open indexdb error’)
}
request.onsuccess=function (e){
myDB.db=e.target.result// 这是一个 IDBDatabase 对象,这就是 IndexedDB 对象
console.log(myDB.db)
}
}
var myDB={
name:’testDB’,
version:’1’,
db:null
}
openDB(myDB.name)
</script>
控制台得到一个 IDBDatabase 对象,这就是 IndexedDB 对象
②关闭 indexdb—-indexdb.close()③删除 indexdb—-window.indexedDB.deleteDatabase(indexdb)
<script>
function openDB(name){
var request=window.indexedDB.open(name)
request.onerror=function(e){
console.log(’open indexdb error’)
}
request.onsuccess=function(e){
myDB.db=e.target.result
callback && callback()
}
}
var myDB={
name:”testDB”,
version:”1″,
db:null
}
openDB(myDB.name,function(){// 回调函数
myDB.db.close()// 关闭 indexdb
window.indexedDB.deleteDatabase(myDB.db)// 删除 indexdb
}
</script>
如果觉得文章对你有些许帮助,欢迎在我的 GitHub 博客点赞和关注,感激不尽!
六、参考
HTML5 本地存储——IndexedDB(一:基本使用)详说 Cookie, LocalStorage 与 SessionStorage