网页存储

网页存储

什么是web存储?

​ web存储指的是在web通信过程中,由客户端(如浏览器)对少量数据进行的本地存储(注:本文所说的是广义的web存储,而不单指Web Storage)。web存储类型主要包括古老的cookie,以及HTML5推出的sessionStorage、localStorage和indexedDB等

常见的浏览器的缓存有:cookie,localStorage,sessionStorage,indexDB.

简介:

​ key/value 单个cookie保存的数据不能超过4kb,每次访问都要传送cookie给服务器,可以设置过期时间,和域名绑定。

​ cookie在前端可以通过document.cookie获得,cookie本身是用encodeURIComponent编码的,因此,如果cookie中包含中文,需要用对应的decodeURIComponent解码才能得到对应值。

​ 除了key和value外,每个参数还会携带其他几个属性,包括域、路径、失效时间、安全标志等,这些参数在使用document.cookie输出时无法看到,不过可以在调试工具中查看:

一般来说,cookie只用于保存与登录相关的信息,其中最重要的是服务端会话(session)对象的id。它不适合存储大量的数据,因为浏览器限制了每个cookie的大小不能超过4KB。此外,浏览器对单个域下cookie的数量也是有限制的,该数量因浏览器而异,对开发者来说,这个数量一般不要超过20个。

sessionStorage

简介:

​ key/value 关闭页面或浏览器后被清除,最大5MB,和域名绑定。

继承自Storge,可以通过window.sessionStorage

sessionStorage.setItem("name", "carter");  // 设置name: carter

sessionStorage.age = "24";   // 设置age: 24

sessionStorage.getItem("name");  // 获取name的值carter

sessionStorage.removeItem("name"); // 删除name

sessionStorage.clear();  // sessionStorage
  • 遵循同源策略,即该存储只在同一个域下可以共享,跨域则无法访问,这样可以保证数据的安全性。
  • sessionStorage拥有5MB的存储空间,并且只能保存字符串类型的数据,对于非字符串类型的数据,一般需要使用JSON.stringify方法压缩成字符串,使用时再用JSON.parse进行解析。
  • 失效时间:sessionStorage与页面会话是绑定的,当某个页面会话失效时,对应的sessionStorage就会被清除。需要注意的是,sessionStorage只在会话页面失效时才会失效。
  • 有效范围:在不跨域的情况下,sessionStorage不可以跨页签生效,

localStorage

简介

​ key/value 一直存储于本地硬盘(浏览器中可以删除),一般数据最大5MB(各个浏览器不一样),和域名绑定。

  • 失效时间:localStorage本身是不会失效的,即使关闭浏览器,下次再访问该网站仍然有效。localStorage没有提供直接设置失效时间的方法,我们需要使用一种特殊的策略来定期清除localStorage。
  • 有效范围:在不跨域的情况下,localStorage可以跨页签生效,

indexDB

简介

​ key/object,可以存储对象,浏览器中的数据库,异步,支持事务,和域名绑定,存储空间大。

尽管5M的空间已经相对较大了,但仍然无法满足所有的前端存储需求。

这是因为前端数据缓存对web站点的性能提升是巨大的(它可以有效减少http数据传输量,而这通常是导致网站卡顿的最主要因素),因此越来越多的站点倾向于在前端存储更多的数据。localStorage和sessionStorage无法满足这样的需求,因为一方面,它们的容量只有5M大小;另一方面,由于是非结构化存储,当数据量较大时,它们的操作速度不够快。

为此,HTML5规范推出了前端的事务型数据库indexedDB。它可以存储大量的结构化数据,具有几乎可以媲美后端数据库的读写性能(当然,从功能和容量上远不及后端数据库)。

特点

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

使用indexedDB大概需要以下几个流程:

  1. 打开数据库:
var request = window.indexedDB.open(databaseName, version);

这样就可以打开或新建一个indexedDB数据库。当所传入的数据库名不存在时,就会新建一个数据库,否则将打开已有数据库。当省略了数据库版本号时,如果数据库已存在,则默认为当前版本,否则版本号为1

  1. 注册处理事件

    调用open方法后,返回的是一个IDBRequest对象,通过向其注册errorsuccessupgradenedded事件,可以处理打开数据的结果。

    error表示数据库打开失败:

request.onerror = function(err){
  console.log("数据库打开失败:" + err);
}

success表示数据库打开成功,此时可以执行数据库读操作:

request.onsuccess = function (event) {
  let db = request.result;
  console.log('数据库打开成功');
};

upgradeneeded表示数据库需要升级,不同于一般的后端数据库,indexedDB每次修改数据库的内容都必须升级数据库版本:

request.onupgradeneeded = function (event) {
  db = event.target.result;
  var objectStore;
  if (!db.objectStoreNames.contains('person')) {
    objectStore = db.createObjectStore('person', { keyPath: 'id' });
  }
}
  1. 增删改查操作

🎃实例开始

  1. 新建数据库

新建数据库与打开数据库是同一个操作,如果指定的数据库不存在,就会新建,后续操作在upgradeneeded事件的监听函数里面完成。

  1. 新建对象仓库-》表
request.onupgradeneeded = function (event) {
  db = event.target.result;
  var objectStore;
  if (!db.objectStoreNames.contains('person')) {
    objectStore = db.createObjectStore('person', 
                                       // 自动创建主键
                                       //{autoIncrement:true}
                                       { keyPath: 'id' }
                                      );
  }
}

解释:判断一个是否存在叫做person的表,N-》新增一张叫做Person的表格,主键为id。

  1. 新建索引
request.onupgradeneeded = function(event) {
  db = event.target.result;
  var objectStore = db.createObjectStore('person', { keyPath: 'id' });
  objectStore.createIndex('name', 'name', { unique: false });
  objectStore.createIndex('email', 'email', { unique: true });
}
  1. 新增数据
function add() {
  var request = db.transaction(['person'], 'readwrite')
    .objectStore('person')
    .add({ id: 1, name: '张三', age: 24, email: 'zhangsan@example.com' });

  request.onsuccess = function (event) {
    console.log('数据写入成功');
  };

  request.onerror = function (event) {
    console.log('数据写入失败');
  }
}

add();

写入数据需要新建一个事务。新建时必须指定表格名称和操作模式("只读"或"读写")。新建事务以后,通过IDBTransaction.objectStore(name)方法,拿到 IDBObjectStore 对象,再通过表格对象的add()方法,向表格写入一条记录。

同时写入操作是一个异步操作,可以通过onsuccess与onerror控制不同的事件操作。

  1. 读取数据
function read() {
   var transaction = db.transaction(['person']);
   var objectStore = transaction.objectStore('person');
   var request = objectStore.get(1);

   request.onerror = function(event) {
     console.log('事务失败');
   };

   request.onsuccess = function( event) {
      if (request.result) {
        console.log('Name: ' + request.result.name);
        console.log('Age: ' + request.result.age);
        console.log('Email: ' + request.result.email);
      } else {
        console.log('未获得数据记录');
      }
   };
}

read();
  1. 遍历数据

    遍历表格中所有的数据,要是有指针对象IDBCursor。

function readAll() {
  var objectStore = db.transaction('person').objectStore('person');

   objectStore.openCursor().onsuccess = function (event) {
     var cursor = event.target.result;

     if (cursor) {
       console.log('Id: ' + cursor.key);
       console.log('Name: ' + cursor.value.name);
       console.log('Age: ' + cursor.value.age);
       console.log('Email: ' + cursor.value.email);
       cursor.continue();
    } else {
      console.log('没有更多数据了!');
    }
  };
}

readAll();
  1. 更新数据
function update() {
  var request = db.transaction(['person'], 'readwrite')
    .objectStore('person')
    .put({ id: 1, name: '李四', age: 35, email: 'lisi@example.com' });

  request.onsuccess = function (event) {
    console.log('数据更新成功');
  };

  request.onerror = function (event) {
    console.log('数据更新失败');
  }
}

update();
  1. 删除数据
function remove() {
  var request = db.transaction(['person'], 'readwrite')
    .objectStore('person')
    .delete(1);

  request.onsuccess = function (event) {
    console.log('数据删除成功');
  };
}

remove();
  1. 使用索引

    索引的意义在于,可以让你搜索任意字段,也就是说从任意字段拿到数据记录。如果不建立索引,默认只能搜索主键(即从主键取值)。

    新建表的时候,对name的字段建立了索引。

    即可以通过name找到对应的数据记录。

    var transaction = db.transaction(['person'], 'readonly');
    var store = transaction.objectStore('person');
    var index = store.index('name');
    var request = index.get('李四');
    
    request.onsuccess = function (e) {
      var result = e.target.result;
      if (result) {
        // ...
      } else {
        // ...
      }
    }
    

参考:

web存储

阮一峰的网站记录

总结:暂时只是记录一个基本概念,后期加上各个的不同点,以及每一个的使用场景。

posted @ 2020-11-14 16:15  且I听  阅读(100)  评论(0)    收藏  举报