前端存储之indexDB

在讲indexDB之前,先简单说说cookie、localStorage、sessionStorage。

cookie

Cookie 是小甜饼的意思。顾名思义,cookie 确实非常小,它的大小限制为4KB左右,是网景公司的前雇员 Lou Montulli 在1993年3月的发明。它的主要用途有保存登录信息,比如你登录某个网站市场可以看到“记住密码”,这通常就是通过在 Cookie 中存入一段辨别用户身份的数据来实现的。

localStorage

localStorage 是 HTML5 标准中新加入的技术,它并不是什么划时代的新东西。早在 IE 6 时代,就有一个叫 userData 的东西用于本地存储,而当时考虑到浏览器兼容性,更通用的方案是使用 Flash。而如今,localStorage 被大多数浏览器所支持,如果你的网站需要支持 IE6+,那以 userData 作为你的 polyfill 的方案是种不错的选择。

sessionStorage

sessionStorage 与 localStorage 的接口类似,但保存数据的生命周期与 localStorage 不同。 Session 这个词的意思,直译过来是“会话”。它只是可以将一部分数据在当前会话中保存下来,刷新页面数据依旧存在。但当页面关闭后,sessionStorage 中的数据就会被清空。

Desktop Chrome Edge Firefox Internet Explorer Opera Safari
localStorage 4 Yes 3.5 8 10.5 4
sessionStorage 5 Yes 2 8 10.5 4
Mobile Android webview Chrome for Android Edge Mobile Firefox for Android Opera for Android iOS Safari
localStorage Yes Yes Yes Yes 10.5 3.2
sessionStorage Yes Yes Yes Yes 11 3.2

cookie、localStorage、sessionStorage异同

特性 Cookie localStorage sessionStorage
数据的生命期 一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效 除非被清除,否则永久保存 仅在当前会话下有效,关闭页面或浏览器后被清除
存放数据大小 4K左右 一般为5MB 一般为5MB
与服务器端通信 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 仅在客户端(即浏览器)中保存,不参与和服务器的通信 仅在客户端(即浏览器)中保存,不参与和服务器的通信
易用性 需要程序员自己封装,源生的Cookie接口不友好 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持

接下来就开始上重头戏了 —— indexDB

indexDB

随着浏览器的功能不断增强,越来越多的网站开始考虑,将大量数据储存在客户端,这样可以减少从服务器获取数据,直接从本地获取数据。

通俗地讲,IndexedDB 就是浏览器提供的本地数据库,它可以被网页脚本创建和操作。IndexedDB 允许储存大量数据,提供查找接口,还能建立索引。这些都是 LocalStorage 所不具备的。就数据库类型而言,IndexedDB 不属于关系型数据库(不支持 SQL 查询语句),更接近 NoSQL 数据库。

操作步骤

查看更多信息参考

  • 创建/打开数据库。
  • 在数据库中创建一个对象仓库(object store)。
  • 启动一个事务,并发送一个请求来执行一些数据库操作,像增加或提取数据等。
  • 通过监听正确类型的 DOM 事件以等待操作完成。
  • 在操作结果上进行一些操作(可以在 request 对象中找到)

打开数据库

var db = null;
var request = window.indexedDB.open("MyTestDatabase");
request.onerror = function(event) {
  // 错误处理
  console.log(' 打开数据库报错');
};
request.onsuccess = function(event) {
  // 成功处理
  db = event.target.result;
  console.log('打开数据库成功');
};

创建和更新数据库版本号

如果指定的版本号,大于数据库的实际版本号,就会发生数据库升级事件upgradeneeded。这时通过事件对象的target.result属性,拿到数据库实例。

var db = null;
request.onupgradeneeded = function (event) {
  db = event.target.result;
}

新建数据库

新建数据库与打开数据库是同一个操作。如果指定的数据库不存在,就会新建。不同之处在于,后续的操作主要在upgradeneeded事件的监听函数里面完成,因为这时版本从无到有,所以会触发这个事件。

通常,新建数据库以后,第一件事是新建对象仓库(即新建表)。

request.onupgradeneeded = function(event) {
  db = event.target.result;
  var objectStore = null;
  if (!db.objectStoreNames.contains('imgLists')) {
    objectStore = db.createObjectStore('imgLists', { keyPath: 'id' });
    // unique name可能会重复
    objectStore.createIndex('name', 'name', { unique: false });
  }
}

创建一张叫imgLists的表格,主键是id。

写入数据

新增数据指的是向对象仓库写入数据记录。这需要通过事务完成。

// new 一个blob对象
var obj1 = {hello: "world"};
var blob = new Blob([JSON.stringify(obj1, null, 2)], {type : 'application/json'});

function add() {
  var request = db.transaction(['imgLists'],  'readwrite')
    .objectStore('imgLists')
    .add({ id: 1, name: '图片1', path: '/static/image', blob:  blob});

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

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

查询数据

查询数据也是通过事物完成。

function read() {
   var transaction = db.transaction(['imgLists']);
   var objectStore = transaction.objectStore('imgLists');
   // 用户读取数据,参数是主键
   var request = objectStore.get(1);

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

   request.onsuccess = function( event) {
      if (request.result) {
        console.log(request.result);
      } else {
        console.log('未获得数据记录');
      }
   };
}

遍历数据

遍历数据表格的所有记录,要使用指针对象 IDBCursor。

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

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

     if (cursor) {
       console.log(cursor);
       cursor.continue();
    } else {
      console.log('没有更多数据了!');
    }
  };
}

更新数据

function update() {
  var request = db.transaction(['imgLists'], 'readwrite')
    .objectStore('imgLists')
    // 主动更新主键为1
    .put({ id: 1, name: '图片2',  path: '/static/image2'});

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

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

删除数据

function remove() {
  var request = db.transaction(['imgLists'], 'readwrite')
    .objectStore('imgLists')
    .delete(1);

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

remove();

创建/使用索引

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

    objectStore.createIndex('name', 'name', { unique: false });
    function findIndex() {
      var transaction = db.transaction(['imgLists'], 'readonly');
      var store = transaction.objectStore('imgLists');
      var index = store.index('name');
      var request = index.get('图片1');

      request.onsuccess = function (e) {
        var result = e.target.result;
        if (result) {
          console.log(result);
        } else {
          // ...
        }
      }
    }

使用场景

indexDB是一个浏览器使用简易的数据库。随着前端功能复杂度提升,用户需要多元化,前端indexDB应用也就越来越多。桌面应用、Progressive Web App(PWA)、chrome扩展组件的开发等。用户同时会获取/操作更多的信息,怎么留存这些大量的数据,那么我们的indexDB就上线了。案例:DevDocs,electron开发的桌面应用(图片传输)。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • 本文介绍本地数据存储的选型。简单总结一些查询到的关于本地数据存储的技术。 控制台展示前端存储 Chrome: 前端...
    谢大见阅读 9,038评论 1 8
  • 本文是我今年2月份发表在博客园上的文章,平常做项目时便温故一下。私以为,只有通过实践才能将知识真正地内化和吸收,再...
    一个笑点低的妹纸阅读 827评论 0 2
  • 一、前言 学习前端的可以关注网页制作web前端部落哦,每天更新干货。web前端技术日新月异,对于浏览器的存储来说,...
    强哥科技兴阅读 874评论 0 0
  • 今天是什么日子 起床:6.00 就寝:11.30 天气:晴 心情:本来下午4点多钟就下班了,想去健身房锻炼下,可是...
    唐青城阅读 149评论 0 0
  • 现在有很多关于熬夜网络用词,比如熬夜冠军、月亮不睡你不睡,你是秃头小宝贝~等一些比较流行的,导致了现在很多网友都喜...
    努力上进的girl阅读 318评论 0 1