by zhangxinxu from http://www.zhangxinxu.com/wordpress/?p=7621
本文可全文转载,但需得到原作者书面许可,同时保留原作者和出处,摘要引流则随意。
更新于2021-03-09
如果项目无需兼容IE浏览器,可以试试使用yux-storage,一样的API,但是代码量少了一个数量级,就100行左右。
https://github.com/yued-fe/yux-storage
一、localforage项目简介
localforage项目地址:https://github.com/localForage/localForage
截止今日(2018-06-03),已经有12000+个星星,万级别的项目。

JS文件下载(右键,另存为):localforage.min.js
localforage用来本地存储数据的。
说到本地存储数据,我们首先想到的是localStorage,应该很多小伙伴都用过,使用很简单。然而,localStorage却有下面一些缺点:
- 存储容量限制,大部分浏览器应该最多5M。我就遇到过localStorage存储字符然后尺寸爆掉的情况。
- 仅支持字符串,如果是存对象还需要将使用JSON.stringify和JSON.parse方法互相转换,有些啰嗦。
- 读取都是同步的。大多数情况下,还挺好使的。但,如果存储数据比较大,例如一张重要图片base64格式存储了,再读可能会有可感知的延迟时间。
localforage的作用就是用来规避上面localStorage的缺点,同时保留localStorage的优点而设计的。从命名上就可以看出两者关系不浅。
localStorage的优点是API非常简单,使用很方便。于是,localforage和localStorage一模一样。
至于localStorage的不足,localforage和使用了其他HTML5 API进行规避,什么API呢?是IndexedDB和WebSQL。
也就是说,localforage的逻辑是这样的:优先使用IndexedDB存储数据,如果浏览器不支持,使用WebSQL,浏览器再不支持,使用localStorage。
然后API还是localStorage的API,也就是数据增删改查通过get,set,remove,clear和length等API。
二、localforage使用案例一则
您可以狠狠地点击这里:localforage存储blob格式的本地上传图片demo
第一次进入这个demo页面,只有一个上传图片按钮。
选择上传图片按钮,则会以blob的形式直接把选择的图片在网页中显示处理,例如:

此时,你再刷新页面,则显示的还是这张图片,因为使用localforage把这张图片以blob数据形式存储在了本地。

相关HTML代码为:
<label for="fileImg">上传图片</label> <input type="file" id="fileImg" accept="image/*" hidden> <p id="result"></p>
然后JS代码如下:
<script src="./localforage.min.js"></script>
<script>
var eleResult = document.getElementById('result');
// 图片资源
var eleImg = document.createElement('img');
// 获取本地存储数据
localforage.getItem('zxxImg', function (err, value) {
if (err == null && value) {
eleImg.src = value;
eleResult.appendChild(eleImg);
}
});
// 选择的本地文件以Blob形式呈现
var reader = new FileReader();
reader.onload = function(event) {
if (!eleImg.src) {
eleResult.appendChild(eleImg);
}
var blob = URL.createObjectURL(new Blob([event.target.result]));
eleImg.src = blob;
// blob本地存储
localforage.setItem('zxxImg', blob);
};
// 选择的文件对象
var file = null;
document.getElementById('fileImg').addEventListener('change', function (event) {
file = event.target.files[0];
// 选择的文件是图片
if (file.type.indexOf("image") == 0) {
reader.readAsArrayBuffer(file);
}
});
</script>
可以看到,虽然localforage的API名称和localStorage一样,但是,在同步还是异步上却不同,localforage是异步执行的,用法示意如下。
localforage.getItem('key', function (err, value) {
// 如果err不是null,则出错。否则value就是我们想要的值
});
更新于2019-08-04
补充一个自己常用的存取组合代码:
// 为了大家任意场景可以粘贴使用,全部改成字面量风格 var storage = {}; var storkey = 'SOME_KEY'; /** * 获取此时的本地存储 */ var getStorage = function (callback) { callback = callback || function () {}; // 获取 localforage.getItem(storkey, function (err, value) { if (err == null && value) { storage = value; } callback(err); }); }; /** * 设置新的本地存储 */ var setStorage = function (callback) { callback = callback || function () {}; // 存储 localforage.setItem(storkey, storage, function (err) { err && console.error(err); callback(); }); };
通常使用先getStorage然后再初始化。
例如:
getStorage(function () {
init();
});
三、localforage和indexDB的区别
indexDB为本地数据库存储,其功能非常强大,再复杂的结构存储都不在话下。localStorage只是使用了其功能中的一部分,很多功能受限,例如,localStorage一次只能存一个字段。
我之前有专门写过文章介绍HTML5 indexedDB,文章名为:“HTML5 indexedDB前端本地存储数据库实例教程”。
indexDB几乎空间无限,性能也不错,各种数据结构都支持,为何总感觉在业内不温不火呢?
我觉得很重要的原因之一就是上手成本,包括2方面:
- 前端需要了解数据库的一些基本概念,例如表,游标,事务,锁等。而业界普遍的前端都是与页面打交道的,数据库操作属于后端的后端了,离的有些远,于是,很多前端都不了解,需要从零开始的数据库学习。
- indexedDB的API又多又长又纷杂,学习成本高,容易记不住,网上好的资源少。
localforage的出现可谓曲线救国,通常我们的数据存储并不需要特别复杂,只要不是完完全全的离线开发,localforage足矣。既不浪费indexDB的好,又避开了indexDB高上手成本的坑。从这个角度看,indexDB应该要谢谢localforage。
当然,如果存储的数据是负责的多行多列表结构,我建议还是老老实实花点功夫学习学习indexDB的使用。
四、结束语
indexDB IE10+浏览器支持。因此,如果想要使用localforage存储任意格式数据,需要注意下浏览器的兼容性问题,例如,本地图片存储Blob数据,IE9肯定是不支持的。这些浏览器怕是只能存字符串了。
一个东西是否有生命力,看的不是其是否强大,而是是否足够简单。
就酱紫,感谢阅读!

//zxx: 今天骑士、勇士第二场,骑士凶多吉少,我觉得第四节很可能会有垃圾时间。第一场着实可惜了。
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:http://www.zhangxinxu.com/wordpress/?p=7621
(本篇完)
相关文章
- 翻译:清除各个浏览器中的数据研究 (0.887)
- HTML5 indexedDB前端本地存储数据库实例教程 (0.660)
- HTML5 localStorage本地存储实际应用举例 (0.491)
- 借助Service Worker和cacheStorage缓存及离线开发 (0.396)
- 翻译-你必须知道的28个HTML5特征、窍门和技术 (0.264)
- 遐想:如果没有IE6和IE7浏览器... (0.264)
- zSlide-基于CSS3/HTML5演示文档jQuery插件 (0.226)
- 本地开发设置个区分明显的favicon吧~ (0.226)
- 如何使用JS检测用户是否缩放了页面? (0.226)
- 醒醒,该使用CookieStore新建和管理cookie了 (0.226)
- 深入Node.compareDocumentPosition API (RANDOM - 0.113)

























