手记

浏览器存储

一、前言

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 可以有效对表单信息进行维护,比如刷新时,表单信息不丢失。

共同点:都是保存在浏览器端,且同源的。

不同点如下:

五、IndexedDB

Web Storage使用简单字符串键值对在本地存储数据,方便灵活,但是对于大量结构化数据存储力不从心,IndexedDB是为了能够在客户端存储大量的结构化数据,并且使用索引高效检索的API。

1.IndexedDB的特点

  • IndexedDB是一种低级API,用于客户端存储大量结构化数据。该API使用索引来实现对该数据的高性能搜索。
  • 为应用创建离线版本

2.IndexedDB的常见操作

在IndexedDB大部分操作并不是我们常用的调用方法,返回结果的模式,而是请求——响应的模式
①建立打开indexdb ----window.indexedDB.open("testDB")
这条指令并不会返回一个DB对象的句柄,我们得到的是一个IDBOpenDBRequest对象,而我们希望得到的DB对象在其result属性中

除了result,IDBOpenDBRequest接口定义了几个重要属性
请求失败的回调函数句柄
onsuccess:请求成功的回调函数句柄
onupgradeneeded:请求数据库版本变化句柄
<script>
function openDB(name){
var request=window.indexedDB.open(name)//建立打开indexdb 
request.=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.=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>

六、参考

6人推荐
随时随地看视频
慕课网APP