各种浏览器存储方式总结

总结cookie、localStorage、sessionStorage、indexedDB这几种浏览器存储方式的差异和优缺点。

前言

  近年来,随着浏览器存储技术的提升,出现了多种前端存储方式。比如:cookie、localStorage、sessionStorage、indexedDB。
  对于前三种方式想必大家耳熟能详,因为cookie、localStorage、sessionStorage都属于js语言的本地存贮,而indexedDB则是一种前端存储数据库。
  这篇文章会分别介绍这四种方式,以及他们之间的差异和优缺点。

一、cookie

1. 什么是cookie

  cookie以“键值对”的形式存在,是一些数据,存储于你电脑上的文本文件中。
  当web服务器向浏览器发送web页面时,在连接关闭后,服务端不会记录用户的信息,而cookie的作用就是用于解决“如何记录客户端的用户信息”:
  当用户访问web页面时,他的名字可以记录在cookie中。在用户下一次访问该网站时,可以在cookie中读取用户访问记录。比如,下次访问同一网站时,用户不必输入用户名和密码就已经登录了(排除用户手动删除cookie情况)。
  大致原理如下图所示:
cookie.png

2. cookie的用法

  将cookie的增删改查封装一下,如下:

 // 添加cookie
function setCookie(key, value, iDay) {
    var oDate = new Date();
    oDate.setDate(oDate.getDate() + iDay);
    document.cookie = key + '=' + value + ';expires=' + oDate;

}
// 删除cookie
function removeCookie(key) {
    setCookie(key, '', -1);//这里只需要把Cookie保质期退回一天便可以删除
}
// 获取cookie
function getCookie(key) {
    var cookieArr = document.cookie.split('; ');
    for(var i = 0; i < cookieArr.length; i++) {
        var arr = cookieArr[i].split('=');
        if(arr[0] === key) {
            return arr[1];
        }
    }
    return false;
}

具体用法可参见Cookie详解

3. cookie的缺陷

  • 每个cookie的大小限制为4KB(每一个name=value为一个cookie),每个站点最多存放20个cookie,每个浏览器一般只允许存放300个cookie。
  • 过多的cookie会带来巨大的性能浪费,因为cookie是紧跟域名的,同一个域名下的所有请求,都会携带cookie。(可以通过存储静态文件的CDN的域名和主站的域名分开来解决)
  • 在http请求中的cookie是明文传递的,所以有安全性问题,除非用https。

4. cookie的典型应用场景

  • 记住密码,下次自动登录。
  • 购物车功能。
  • 记录用户浏览数据,进行商品(广告)推荐。

二、localStorage

1. 什么是localStorage

  localStorage保存的数据,以“键值对”的形式长期存在。也就是说,每一项数据都有一个键名和对应的值,所有的数据都是以文本格式保存。保存的数据没有过期时间,直到手动去除。
  localStorage可以作为浏览器本地缓存方案,用来提升网页首屏渲染速度(第一次请求返回时,将一些不变信息直接存储在本地)

2. localStorage的用法

// 存储
localStorage.setItem("lastname", "Smith");
// 检索
document.getElementById("result").innerHTML = localStorage.getItem("lastname");

具体用法可参见JavaScript 存储对象

3. localStorage的特点

  • 保存的数据长期存在,下一次访问该网站的时候,网页可以直接读取以前保存的数据。
  • 大小为5M左右。
  • 仅在客户端使用,不和服务端进行通信。
  • 接口封装较好。

4. localStorage的典型应用场景

  考虑到localStorage的特点之一是持久,有时我们更倾向于用它来存储一些内容稳定的资源。比如图片内容丰富的电商网站会用它来存储base64格式的图片字符串。

三、sessionStorage

1. 什么是sessionStorage

  sessionStorage保存的数据用于浏览器的一次会话,当会话结束(通常是关闭窗口或标签页),数据被清空。
  sessionStorage特别的一点在于,即便是相同域名下的两个页面,只要它们不在同一个浏览器窗口中打开,那么它们的sessionStorage内容便无法共享;localStorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。除了保存期限的长短不同,sessionStorage的属性和方法与localStorage完全一样。

2. sessionStorage的用法

// 存储
sessionStorage.setItem("lastname", "Smith");
// 检索
document.getElementById("result").innerHTML = sessionStorage.getItem("lastname");

具体用法可参见JavaScript 存储对象

3. sessionStorage的特点

  • 会话级别的浏览器存储。
  • 大小为5M左右。
  • 仅在客户端使用,不和服务端进行通信。
  • 接口封装较好。

4. sessionStorage的典型应用场景

  • 维护表单信息,比如刷新时,表单信息不丢失。
  • 微博的sessionStorage存储了本次会话的浏览足迹,lasturl对应的就是你上一次访问的url地址,这个地址是即时的。当你切换url 时,它随之更新,当你关闭页面时,留着它也确实没有什么意义了,于是可以释放掉。

四、cookie、localStorage、sessionStorage对比

1. 相同点

  • 都是保存在浏览器端,且都是字符串类型的键值对。
  • 都遵循同源策略

2. 不同点

  • 传递方式不同
    cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。sessionStorage和loaclStorage不会自动把数据发给服务器,仅在本地保存。
  • 数据大小不同
    cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。存储大小限制也不同,cookie数据不能超过4KB,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。
    sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或者更大。
  • 数据有效期不同
    cookie:只在设置cookie过期时间之前一直有效,即使窗口或浏览器关闭;
    localStorage:始终有效,窗口或浏览器关闭也一直保存,除非手动删除,因此用作持久数据;
    sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持。
  • 作用域不同
    cookie:在所有同源窗口中都是共享的;
    localStorage:在所有同源窗口中也都是共享的;
    sessionStorage:不在不同的浏览器窗口中共享,即使是同一个页面。

五、indexedDB

1. 什么是indexedDB

  为了弥补cookie的局限性,HTML5中新增了本地存储的解决方案:Web Storage(localStorage和sessionStorage)。
  可事实上无论是cookie还是Web Storage,都只能用于存储少量的简单数据。当遇到大规模的、结构复杂的数据时,我们就需要用到indexedDB了。
  indexedDB是一个运行在浏览器上的非关系型数据库,用于客户端存储大量结构化数据(包括文件和blobs)。因为它是nosql的,数据形式使用的是json。理论上来说,indexedDB是没有存储上限的(一般来说不会小于250M)。它不仅可以存储字符串,还可以存储二进制数据。

2. indexedDB的用法

  具体用法可参见IndexedDB中文文档

3. indexedDB的特点

  • 键值对储存
  • 异步
  • 支持事务
  • 同源限制
  • 储存空间大
  • 支持二进制储存

六、总结

  近年来随着浏览器存储、缓存技术的出现和发展,为前端应用带来了无限的转机,此外还衍生出了PWA这样优秀的Web应用模型。
  总结下本文几个核心观点:

  • cookie的本职工作并非本地存储,而是“维持状态”;
  • Web Storage是HTML5专门为浏览器存储而提供的数据存储机制,不与服务端发生通信;
  • indexedDB 用于客户端存储大量结构化数据。


原文出处
https://github.com/ljianshu/Blog/issues/55
https://segmentfault.com/a/1190000011145364


  目录