揭秘前端存储

1,962 阅读8分钟

最近在项目中使用了部分的前端存储,之前只有一些简单的了解,今天就趁这个机会把前端存储进行深入研究一番。

写在开始

前端存储的好处:

  • 方便网页的加载,避免了在发送请求收到响应前页面的空白期。
  • 也可以在非强制性要求实时最新数据时减少向服务端的请求,加快渲染速度。
  • 在网络不佳或无网络时仍有离线数据可以查看。

前端存储的方式:

首先我们应该先清除大概都有哪些存储方式,对此我们只需要打开控制台,选择 application 来进行查看。

A5HpRI.jpg

我们可以看到,存储大概分为两大类,一类为 存储类 ,另一类为 缓存类

存储类:
  • Web存储 (Web Storage):HTML 5 中提出的存储方式,容量有 5 M。

    • localStorage
    • sessionStorage
  • Cookie:浏览器普遍支持的基于 HTTP 协议的存储方式,但容量只有 4 KB

  • 数据库存储:

    • IndexDB
    • Web SQL
缓存类:
  • Cache Storage: 在 Service Worker 的规范中提出,一般配合 Service Worker 进行离线缓存。
  • Application Cache: 在 HTML5.1提出的缓存方式,可用来构建离线应用。

介绍

个子小的长兄 —— Cookie

HTTP Cookie,它最初适用于客户端存储会话信息的、这个标准要求服务器对 HTTP 请求设置 Set-Cookie HTTP 头作为响应的一部分,其中会包含有会话信息。浏览器在 Cookie 中存储绘画信息,并在发送请求时将 Cookie 一起发送过去。

Cookie 的构成

我们先打开 github 之后进入控制台查看一下

AIgIEt.jpg

  • 名称
  • 路径
  • 失效时间 (格林威治时间)
  • 大小
  • 是否为 HTTP请求
  • 安全性

域 路径 失效时间 和 安全性 都是服务器给浏览器的指示,他们不会随着请求发送给服务器,发送给服务器的只有名称与值对。

Cookie 的限制性

  • 如果设定了 Cookie 的过期时间,那么 Cookie 会在到期时自动失效。
  • 如果没有设定过期时间,那么 Cookie 就是 session 级别的,即浏览器关闭时 Cookie 自动消失。

Cookie 的优缺点

优点:

1. 可以控制过期时间,不会永久有效,有一定的安全保障。
2. 可进行扩展,可跨域共享。
3. 通过加密与安全传输技术 (SSL) ,可以减少 Cookie 被破解的可能性。
4. 有较高的兼容性。

缺点:

1. 有一定的数量与长度限制,每个 Cookie 长度不能超过 4 KB ,否则超出部分会被截掉。
2. 请求头上的数据容易被拦截攻击。

新生力量 Web Storage

LocalStorage 与 SessionStorage

我们可以先看一下它的兼容性,许多浏览器已经完全支持了它:

AIW1HA.md.jpg
AIWlBd.md.jpg

数据来源: MDN

出现原因

  • 克服 Cookie 的一些限制,同时存储一些需要严格控制在客户端,不需要发送给服务器的一些数据。
  • 提供了除 Cookie 之外的另一种存储会话的途径。
  • 提供了一种大容量存储空间来跨回话存储数据的途径。

如何查看

它们都是直接作为 window对象的属性存在的,我们可以直接通过 window.localStoragewindow.sessionStorage 来访问。

AIf7Zj.jpg

同时,我们观察到 Web Storage 只能储存字符串,如果用 Web Storage 存储对象,会出现 [Object Object], 可以用 JSON.stringifyJSON.parse方法来解决这个问题。

Web Storage 实例方法

  • clear:删除所有值
  • getItem(name): 根据传入的键来获取对应的值。
  • key(index): 获得所对应索引的键,名称。
  • removeItem(name): 删除键对应的键值对
  • setItem(name, value): 为指定的 name 设置一个对应的值。
没有感情的 sessionStorage
  • 同源策略: 不同于 Cookie, sessionStorage 访问限制更高,只有当前设定了 sessionStorage 的域下才能访问。
  • 单标签页: 两个相同域下的标签页不能互通。
  • 在关闭标签页或者新开的标签页下都不能访问之前写下的 sessionStorage
  • 刷新标签页依然可以访问 sessionStorage

使用的场景:

1. 主要针对会话级的小数据的存储。
2. 存储一些在当前页面刷新仍然需要存储,但是关闭后不需要留下的信息。
3. 很适合单页应用的使用,可以用来存储登录态信息等。

不离不弃的 localStorage

  • 同源策略:和 sessionStorage 一样,要访问同一个 localStorage 页面必须来自同一个域名,同种协议,同种端口。
  • localStorage 设定后,刷新或者重新打开标签页,关闭浏览器重新打开原来的标签页也可以访问到。

使用的场景:

1. 持久性的保存客户端数据,只能通过 JavaScript 删除或者用户清除浏览器缓存。
2. 如果有一些稍大量的数据,例如编辑器的自动保存等。
3. 多页面间访问共同数据。 sessionStorage 只能用于一个标签页,而localStorage可以在多个标签页之间共享。

sessionStorage 与 localStorage 的区别

  • 生命周期:localStorage 是本地存储,没有期限,只能用户自己操作来删除。 sessionStroage 是会话存储,页面关闭数据就会丢失。
  • sessionStorage 有单标签页的限制,localStorage则没有。

Storage 事件

我们对 Storage 对象进行任何的操作,都会在文档上触发 Storage 事件, 这个事件的 event 对象有以下属性:

  • domain:发生变化的存储空间的域名。
  • key:设置或删除的键名
  • newValue: 如果是设置值,则是新值。如果是删除键,则为null。
  • oldValue:键被更改之前的值。

数据库级别: IndexDB 与 Web SQL

Web SQL 类似关系型数据库, 它使用 sql 语句进行相关操作。

indexDB 类似 NoSQL , 直接使用 js 的方法操作数据。

特点:

  • 访问:indexDB 和 Web SQL 和 Web Storage 一样,均是只能在创建数据库的域名下才能访问。
  • 存储时间:存储时间为永久,除非用户清除数据,他可用作长期的存储。
  • 大小限制:二者其实没有强制限制。只是 indexDB 在数据超过 50 M 之后会从浏览器弹出一个框让你确认。
  • 性能: indexDB 查询速度会相对较慢,而 Web SQL 的性能相对较快。

实际操作

第一步打开数据库

var request = indexedDB.open(name, version);

第一个参数为数据库的名称,第二个参数为数据库的版本号。

第二步添加数据

创建事务,并加上数据读写权限。

var transaction = db.transaction(storeName, 'readwrite');

获取 objectStore 再调用add方法添加数据

var store = transaction.objectStore(storeName);
var request = store.get(key);
request.onsuccess = function (e) {
    data = e.target.result;
    console.log(student.name);  
};

第三步删除数据

删除也需要创建事务,调用删除接口 ,通过key删除对象。

var transaction = db.transaction(storeName, 'readwrite');
var store = transaction.objectStore(storeName);

store.delete(key);

第四步查找数据

  • 按key查找

    开启事务,获取到 objectStore ,调用get()方法获取对象。

    var transaction = db.transaction(storeName, 'readwrite');
    var store = transaction.objectStore(storeName);
    var request = store.get(key);
    request.onsuccess = function (e) {
        data = e.target.result;
        console.log(student.name)
    };
    
  • 使用索引查找

    我们在使用索引之前需要先创建索引,它使用 createIndex方法创建索引,方法有三个参数: 索引名称、索引属性字段名,索引属性值是否唯一。

    objectStore.createIndex('name','name', {
        unique: false
    })
    

    创建好了索引,我们就可以使用索引进行查询:

    var transaction = db.transaction(storeName);
    var store = transaction.objectStore(storeName);
    var index = store.index(search_index);
    index.get(value).onsuccess = function (e) {
        data = e.target.result;
        console.log(student.id);
    }
    
  • 游标遍历数据

    var transaction = db.transaction(storeName);
    var store = transaction.objectStore(storeName);
    var request = store.openCursor(); //成功打开游标
    var dataList = new Array();
    var i = 0;
    request.onsuccess = function (e) {
        var  cursor = e.target.result;
        if (cursor) {
            console.log(cursor.key);
            dataList[i] = cursor.value;
            console.log(dataList[i].name);
            i++;
            cursor.continue();
        }
        data = dataList;
    }
    

第五步,更新对象

为了更新对象,我们首先要把它取出来,进行修改之后再放回去。

var transaction = db.transaction(storeName, 'readwrite');
var store = transaction.objectStore(storeName);
var request = store.get(key);
request.onsuccess = function (e) {
    var data = e.target.result;
    for (a in newData) {
        data.a = newData.a;
    }
    store.put(data);
}

第六步,关闭与删除

关闭数据库需要调用数据库的 close 方法

db.close();

删除数据库使用数据库对象 deleteDatabase 方法

function deleteDB (name) {
    indexedDB.deleteDatabase(name);
}

IndexDB 特点

  • 它的数据保存在对象存储空间中。
  • 创建对象存储空间,首先先定义一个键,之后添加数据。
  • 可以使用游标查询。

indexDB 的兼容性还是一大问题,Web SQL 虽然过时,但兼容性却仍然非常好,移动端几乎均可用。

Cache Storage

Cache Storage 是用来存储 Response 对象 ,也就是对 HTTP 响应进行缓存。 Cache Storage 是多个 cache 的集合,每个 cache 可以存储多个响应对象。它基于 Promise。这里不做详细的赘述。

Application Cache

它是 HTML5 中新引入的应用程序换粗技术,它的出现意味着 web 应用可以通过缓存,在没有网络的环境下运行,构建离线应用。

优点:

  • 离线浏览
  • 提升页面的载入速度
  • 降低服务器的压力

一般来说 Application Cache 只用来存储一些静态资源,它的使用方式主要需要两个步骤:

1.服务端维护一个 manifest清单

2.浏览器端进行一个设置。

<html manifest="demo">

一般的,我们必须给 manifest 文件设置正确的 MIME-type 为 "text/cache-manifest",它需要在服务器端进行配置。

在 Progressive Web Application 中, Application Cache 配合 Service Worker 承担着主要的任务。

参考文献

MDN: LocalStorage , sessionStorage, indexDB

本地存储与离线存储

前端存储之IndexDB