大家好,我是前端队长Daotin,想要获取更多前端精彩内容,关注我,解锁前端成长新姿势。
全文阅读大概需要8分钟,建议先收藏后看。
以下正文:
今天看到有人在群里提问说,有一个业务场景,用户上传图片后,图片要回显,不依赖后端,刷新浏览器后也会显示,我是存放在localStorage
里面,如果图片超过5MB就超过最大存储了,有没有什么办法?
首先他这个问题让我想到,在开发项目的时候的一些对于上传图片后,图片回显的操作,这里我进行总结一下。
一般都是在图片上传后(不清楚如果上传图片的可以参考这篇文章:前端如何上传文件),后端会给我们返回一个上传成功后的图片地址,然后我们用该地址替换到img标签的src即可,这是常规操作。
不依赖后端就是图片上传后,图片的预览不使用后端返回的图片地址,而是前端通过上传的图片自己显示。
图片一次性回显
的意思是,在上传成功后回显,但是刷新界面后,图片就不显示了,相当于只是临时看看当时上传的图片。
这种方式操作很简单,有两种方式。
一般图片上传,我们会采用formData
的形式上传到服务器。于是formData形式的数据,我们可以使用FileReader
来读取到base64格式的图片进行显示。
示例代码如下:
<body>
<img src="" alt="">
<input type="file">
</body>
// js代码
var inputDom = document.querySelector('input');
var imgDom = document.querySelector('img');
inputDom.onchange = function () {
// 创建一个formData对象,后期通过ajax上传到服务器
let formData = new FormData();
formData.append("iFile", this.files[0]);
let file = formData.get('iFile');
console.log('==>', file);
// 后期取到file文件
let reader = new FileReader();
let fileType = file.type;
// 调用reader进行读取
reader.readAsDataURL(file);
// reader读取完成
reader.onload = function (e) {
if(/^image\/[jpeg|png|gif]/.test(fileType)) {
imgDom.src = e.target.result;
}
}
}
下图是img的src:
createObjectURL函数可以创建一个引用任何数据的简单URL字符串。然后用这个url作为img的src即可进行图片回显。
代码很简单,如下:
var inputDom = document.querySelector('input');
var imgDom = document.querySelector('img');
inputDom.onchange = function () {
// 创建一个本地file文件的临时url
var objectURL = window.URL.createObjectURL(this.files[0]);
console.log(src);
imgDom.src = src;
}
下图是img的src:
参考链接:
图片永久回显就是页面刷新后,图片依然回显。
目前可以采用的方式为localStorage
存储在本地,但是如果图片数据过大(大于10M,目前浏览器localStorage 在 2.5MB 到 10MB 之间),那么就需要一种新的解决方案,那就是本文的主角:indexedDB
。
通俗地说,IndexedDB
就是浏览器提供的本地数据库,它可以被 JavaScript 脚本创建和操作。IndexedDB 允许储存大量数据,提供查找接口,还能建立索引。这些都是 localStorage 所不具备的。
IndexedDB
的数据是存在硬盘
上的,具体有多大呢?Chrome 对IndexedDB 储存空间限制的定义是:硬盘可用空间的三分之一。
在IndexedDB之前,还有个WebSQL 数据库,但是W3C组织在2010年11月18日废弃了webSql。尽管两者都是存储的解决方案,但是他们提供的不是同样的功能。IndexedDB 和WebSQL的不同点在于WebSQL 是关系型数据库访问系统,IndexedDB 是索引表系统(key-value型)。
至于为什么会被废弃,可以参考这篇文章:HTML5 indexedDB前端本地存储数据库实例教程
IndexedDB的基本操作可以参考阮一峰老师写的:浏览器数据库 IndexedDB 入门教程,非常详细,这里我就不必在重复一遍了。
阮一峰老师写的IndexedDB 操作教程都是基于原生IndexedDB API进行操作的,有时候是比较繁琐的,那有没有一些成熟的封装好的js库供我们使用呢?
答案当然是有的,还不少呢,有了这些封装库,我们可以更快更简单进行IndexedDB的操作。
基本上IE10+
都支持。https://caniuse.com/?search=indexedDB
1、localForage (19K star)
localForage是一个快速,简单的JavaScript存储库。 localForage通过使用简单的类似于localStorage的API使用异步存储(IndexedDB或WebSQL)来改善Web应用程序的离线体验。localForage在不支持IndexedDB或WebSQL的浏览器中会自动使用localStorage。
Github地址:https://github.com/localForage/localForage
2、PouchDB(14.1K star)
PouchDB是一个受Apache CouchDB启发的开源JavaScript数据库,旨在在浏览器中良好运行。 PouchDB的创建是为了帮助Web开发人员构建脱机工作以及在线工作的应用程序。 它使应用程序可以在脱机时在本地存储数据,然后在应用程序重新联机时将其与CouchDB和兼容服务器同步,从而使用户的数据无论在下次登录时都保持同步。
(感觉像是在线办公软件的临时离线场景,不适用于本节意义上的纯离线场景)
Github地址:https://github.com/pouchdb/pouchdb
3、Dexie.js(6.6K star)
Dexie.js是indexedDB的封装库。
Github地址:https://github.com/dfahlander/Dexie.js
4、idb(3.7K star)
这是一个很小的库(大约1.09k),主要反映了IndexedDB API,但是有一些小的改进,对可用性产生了很大的影响。
Github地址:https://github.com/jakearchibald/idb
(完)
(added in 20211231)
衍生阅读: