一、本地存储历程

- 最早的Cookies,问题主要就是太小,大概也就4KB的样子,而且IE6只支持每个域名20个cookies,太少了。优势就是大家都支持,而且支持得还蛮好。很早以前那些禁用cookies的用户也都慢慢的不存在了,就好像以前禁用javascript的用户不存在了一样。
- userData是IE的东西,垃圾。Flash吧,空间是Cookie的25倍,基本够用。再之后Google推出了Gears,虽然没有限制,但不爽的地方就是要装额外的插件。
- 到了HTML5把这些都统一了,官方建议是每个网站5MB,非常大了,就存些字符串,足够了。比较诡异的是居然所有支持的浏览器目前都采用的5MB,尽管有一些浏览器可以让用户设置,但对于网页制作者来说,目前的形势就5MB来考虑是比较妥当的。
IndexDB是一个相对底层一点API。通常用于存储大量结构化数据,包括文件、Blob等。IndexDB的API使用索引来实现对数据的高性能读取。
localStorage、sessionStorage是浏览器最常用的数据存储方案。两个各有优缺点。
- localStorage支持持久性存储,浏览器会话结束依旧可以存储数据在浏览器内存中,方便下次数据读取与使用。但缺点是存储的大小有限制,不同的浏览器基于的存储空间有所区别,但是都在5M左右。对于普通的业务场景足够胜任。但是对于通讯应用,存储对话记录这种高密度数据存储的场景来说,内存空间完全是不够用的。
- sessionStorage支持会话存储,浏览器相同域名会话窗口之间支持内存数据共享。当会话结束之后,关闭会话窗口,内存数据会被清除。缺点很明显,会话不支持永久存储,同时内存空间也很小。
三者都是基于源(Origin)的对象存储。源(Origin)指的是协议、域名、端口。不同的源数据是不支持共享的,相互之间保持独立,能够完美的避免不同源的数据污染。
www.baidu.com和www.google.com两个是不同的源,数据均不支持共享。
如果不同源数据支持共享会造成严重的数据污染,如下面的场景:
www.baidu.com源存储了一个数据 键为a,值为b
www.google.com源存储了一个数据 键为a,值为b
两键值对修改会造成相互相应,从而引发数据污染。
二、localStorage
在HTML5中,本地存储是一个window的属性,包括localStorage和sessionStorage,从名字应该可以很清楚的辨认二者的区别,前者是一直存在本地的,后者只是伴随着session,窗口一旦关闭就没了。二者用法完全相同。
1.如何创建和访问 localStorage
(1)方式一:点的方式操作
localStorage.lastname="Smith";
document.write(localStorage.lastname);
(2)方式二:存储API方式操作
- 调用
setItem()方法,将对应的名字和值传递出去,可以实现数据存储 - 调用
getItem()方法,将名字传递出去,可以获取对应的值 - 调用
removeItem()方法,名称作为参数,可以删除对应的数据 - 调用
clear()方法,可以删除所有存储的数据 - 使用
length属性以及key()方法,传入0~length-1的数字,可以枚举所有存储数据的名字
localStorage.setItem("name", "haorooms"); // 以"name"为名字存储一个字符串
localStorage.getItem("name"); // 获取"name"的值
// 枚举所有存储的名字/值对
for(var i=0; i<localStorage.length; i++){ // length表示所有的名值对总数
var name = localStorage.key(i); // 获取第i对的名字
var value = localStorage.getItem(name); // 获取该对的值
}
localStorage.removeItem("name"); // 删除"name"项
localAStorage.clear(); // 全部删除
三、sessionStorage
sessionStorage用法和Localstorage用法一样,区别就是,sessionStorage是会话存储,关闭浏览器,存储内容就会被清除。
需要注意的是,HTML5本地存储只能存字符串,任何格式存储的时候都会被自动转为字符串,所以读取的时候,需要自己进行类型的转换
四、IndexDB
webStorage最显著的缺点是
- 存储空间太小
- 键值对总是以字符串形式存储,不支持其他数据格式,如Blob、ArrayBuffer
- 不支持异步操作,数据量大时进行I/O操作性能体验差
IndexDb成为了如上问题的解决方案。
空间大小
IndexDB存储空间根据不同的设备而定,因为不同设备存储空间大小不一致,浏览器的最大存储空间是动态的,它完全取决于你的磁盘大小。全局限制为可用磁盘空间的 50%。在 Firefox 中,一个名为 Quota Manager 的内部浏览器工具会跟踪每个源用尽的磁盘空间,并在必要时删除数据。
因此,如果你的硬盘驱动器是 500GB,那么浏览器的总存储容量为 250GB。如果超过此范围,则会发起称为源回收的过程,删除整个源的数据,直到存储量再次低于限制。删除源数据没有只删一部分的说法——因为这样可能会导致不一致的问题。
另外一个是当存储空间达到上限之后会执行LRU策略,当可用磁盘空间已满时,配额管理器将根据 LRU 策略开始清除数据——最近最少使用的源将首先被删除,然后是下一个,直到浏览器不再超过限制。
异步执行
IndexDB执行的操作都是异步完成的,以免阻塞应用程序。
由于存储不涉及到浏览器的Document操作,因此我们还可以配合Web Worker实现数据交互。把IndexDB的操作都放在Web Worker中,大大提升性能。
五、localforage
localForage 是基于 IndexedDB 封装的前端存储库,本质上是 IndexedDB 的 “易用版封装层”—— 它以 IndexedDB 为核心底层实现,同时兼容 WebSQL、localStorage(降级方案),目的是解决原生 IndexedDB API 繁琐、难用的问题。
localstorage 有几个问题:
- 它是同步的,不管数据多大,我们需要等待数据从磁盘读取和解析,这会减慢我们的应用程序的响应速度,如果放到移动设备上,可想而之。
- 仅支持字符串,如果是存对象还需要将对象
JSON.stringify({name:”houyuewei”,age:20})下,用的时候再次转换,真是麻烦。 - 不能加密存储到硬盘上,增加了很多危险性。
- 永久存储,并且存储容量限制在
10M
localForage出现的原因
LocalForage就解决了上面的问题,Mozilla 开发了一个叫 localForage 的库 ,使得离线数据存储在任何浏览器都是一项容易的任务。localForage 是一个使用非常简单的 JavaScript 库的,提供了 get,set,remove,clear 和 length 等等 API,还具有以下特点:
- 支持回调的异步 API;
- 支持 IndexedDB,WebSQL 和 localStorage 三种存储模式;
- 支持 BLOB 和任意类型的数据,让您可以存储图片,文件等。
- 支持 ES6 Promises
- 支持angularjs,requires,embers等
eg:
- 回调基本写法
localforage.setItem('key', 'value', function (err) {
// if err is non-null, we got an error
localforage.getItem('key', function (err, value) {
// if err is non-null, we got an error. otherwise, value is the value
});
});
- Promise
localforage.setItem('key', 'value').then(function () {
return localforage.getItem('key');
}).then(function (value) {
// we got our value
}).catch(function (err) {
// we got an error
});
async/await
try {
const value = await localforage.getItem('somekey');
// This code runs once the value has been loaded
// from the offline store.
console.log(value);
} catch (err) {
// This code runs if there were any errors.
console.log(err);
}