浏览器存储 您所在的位置:网站首页 浏览器存储空间异常 浏览器存储

浏览器存储

2024-07-10 11:55| 来源: 网络整理| 查看: 265

文章目录 前言一、IndexedDB是什么?二、使用步骤1、封装常用方法(创建构造函数)2、实例化并执行各种操作初始化数据库添加数据删除数据更新数据查询数据关闭数据库

前言

IndexedDB是一个事务数据库系统,类似于基于SQL的RDBMS。然而,与使用固定列表的基于SQL的RDBMS不同,IndexedDB是一个基于JavaScript的面向对象数据库。

为啥要使用呢?

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

现有的浏览器数据储存方案,都不适合储存大量数据:Cookie 的大小不超过4KB,且每次请求都会发送回服务器;localStorage 和 sessionStorage 在 2.5MB 到 10MB 之间(各家浏览器不同),而且不提供搜索功能,不能建立自定义的索引。所以,需要一种新的解决方案,这就是 IndexedDB 诞生的背景。

一、IndexedDB是什么?

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

IndexedDB 具有以下特点。

键值对储存。 IndexedDB 内部采用对象仓库(object store)存放数据。所有类型的数据都可以直接存入,包括 JavaScript 对象。对象仓库中,数据以"键值对"的形式保存,每一个数据记录都有对应的主键,主键是独一无二的,不能有重复,否则会抛出一个错误。

异步。 IndexedDB 操作时不会锁死浏览器,用户依然可以进行其他操作,这与 LocalStorage 形成对比,后者的操作是同步的。异步设计是为了防止大量数据的读写,拖慢网页的表现。

支持事务。 IndexedDB 支持事务(transaction),这意味着一系列操作步骤之中,只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。

同源限制 IndexedDB 受到同源限制,每一个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能访问跨域的数据库。

储存空间大 IndexedDB 的储存空间比 LocalStorage 大得多,一般来说不少于 250MB,甚至没有上限。

支持二进制储存。 IndexedDB 不仅可以储存字符串,还可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)。

更多详细的介绍可移步这里查看

二、使用步骤 1、封装常用方法(创建构造函数)

模块化开发是前端必备技巧,下面咱简单封装个IndexDBCache类,用于增、删、改、查 操作

const indexDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB; export class IndexDBCache { constructor( params = { dbName: "test", // 数据库名 cacheTableName: "imageCache", // 表名 keyPath: "imageName", // 设置主键 (需要为添加对象内的key,否则新增和获取都会失败) indexs: [], // 设置索引 } ) { this._db = null; // 数据库 this._transaction = null; // 事务 this._request = null; // 打开数据库返回的事务 this._dbName = params.dbName; // 数据库名 this._cacheTableName = params.cacheTableName; // 表名 this._dbversion = 1; // 数据库版本 this._keyPath = params.keyPath; // 设置主键 this._indexs = params.indexs; // 设置索引 } // 初始化数据库 initDB() { return new Promise((resolve, reject) => { // 打开数据库 this._request = indexDB.open(this._dbName, this._dbversion); // 数据库初始化成功 this._request.onsuccess = (event) => { this._db = this._request.result; resolve(event); }; // 数据库初始化失败 this._request.onerror = (event) => { reject(event); }; // 数据库初次创建或更新时(指定的版本号,大于数据库的实际版本号)会触发 this._request.onupgradeneeded = (event) => { // 这时通过事件对象的target.result属性,拿到数据库实例。 const db = event.target.result; if (!db.objectStoreNames.contains(this._cacheTableName)) { const objectStore = db.createObjectStore(this._cacheTableName, { keyPath: this._keyPath, }); this._indexs.forEach(element => { // 三个参数分别为索引名称、索引所在的属性、配置对象(说明该属性是否包含重复的值) objectStore.createIndex(element.name, element.name, { unique: element.unique }); }); } resolve(event); }; }); } /** * @description : 新增数据 * @param {Object} params 添加到数据库中的数据 { imageName: 文件名, image: base64格式图片 } * @return {*} */ addData(params) { return new Promise((resolve, reject) => { const transaction = this._db.transaction( this._cacheTableName, "readwrite" ); const store = transaction.objectStore(this._cacheTableName); const response = store.add(params); response.onsuccess = (event) => { resolve(event); }; response.onerror = (event) => { reject(event); }; }); } // 删除指定主键值 remove(key) { var request = this._db.transaction([this._cacheTableName], 'readwrite') .objectStore(this._cacheTableName) .delete(key); request.onsuccess = function (event) { console.log('数据删除成功'); }; } // 清空数据库数据 clearDB() { return new Promise((resolve, reject) => { const transaction = this._db.transaction( this._cacheTableName, "readwrite" ); const store = transaction.objectStore(this._cacheTableName); const response = store.clear(); response.onsuccss = (event) => { resolve(event); }; response.onerror = (event) => { reject(event); }; }); } // 通过主键读取数据 getDataByKey(key) { return new Promise((resolve, reject) => { const transaction = this._db.transaction(this._cacheTableName); const objectStore = transaction.objectStore(this._cacheTableName); // 通过主键读取数据 // const request = objectStore.get(key); // getAll(key)同get(key)获取指定key对应数据,如果getAll不传参或者传null即返回所有数据 const request = objectStore.getAll(key); request.onsuccess = () => { resolve(request.result); }; request.onerror = (event) => { reject(event); }; }); } // 通过主键读取数据 getDataByIndex(params) { const transaction = this._db.transaction([this._cacheTableName], 'readonly'); const store = transaction.objectStore(this._cacheTableName); const index = store.index(params.index); const request = index.get(params.value); request.onsuccess = function (e) { const result = e.target.result; console.log('getDataByIndex', result) } } // 遍历数据 readAll() { const objectStore = this._db.transaction(this._cacheTableName).objectStore(this._cacheTableName); objectStore.openCursor().onsuccess = function (event) { const cursor = event.target.result; if (cursor) { console.log('key: ' + cursor.key); console.log('Value: ' + JSON.stringify(cursor.value)); cursor.continue(); } else { console.log('没有更多数据了!'); } }; } // 更新指定主键数据 update(params) { var request = this._db.transaction([this._cacheTableName], 'readwrite') .objectStore(this._cacheTableName) .put(params); request.onsuccess = function (event) { console.log('数据更新成功'); }; request.onerror = function (event) { console.log('数据更新失败'); } } // 关闭数据库 closeDB() { this._db.close(); } // 删除数据库 deleteDB() { console.log('开始删除数据库') let DBDeleteRequest = indexDB.deleteDatabase(this._dbName) DBDeleteRequest.onsuccess = function (event) { console.log('删除数据库成功') } DBDeleteRequest.onerror = function (event) { console.log('删除数据库失败') } } } 2、实例化并执行各种操作 初始化数据库 // 根据项目实际需求,设置对应数据库名、表名和数据库主键(主键需要为添加对象内的key,否则新增和获取会失败) const params = { dbName: "test", cacheTableName: "imageCache", keyPath: "imageName", indexs: [ {name: 'imageData', unique: false}, {name: 'imageFile', unique: true} ] } let imageDB = new IndexDBCache(params) const initIndexDB = () => { imageDB.initDB().then(res => { if (res.type == 'upgradeneeded') { console.log('indexDB 数据库创建或更新成功!') } else { console.log('indexDB 数据库初始化成功!') } }).catch((err) => { console.log('indexDB 数据库初始化失败! ', err) }) }

在这里插入图片描述

添加数据 function RandomNumber() { return Math.floor(Math.random() * 100000000.0) } const changeVal = () => { const data = { imageName: 'uploadImgName' + RandomNumber(), imageData: 'uploadImgUrl' + RandomNumber(), imageFile: 'uploadFile' + RandomNumber() } imageDB.addData(data).then((res) => { console.log('写入 indexDB 数据库成功', res) }).catch((err) => { console.log('写入 indexDB 数据库失败==>', err) }) }

添加的时候需要注意添加对象内的key是否有存在于keyPath中,如果都没有,那么新增数据会导致失败,如下图 在这里插入图片描述

删除数据 删除指定主键值 const removeIndexDB = () => { imageDB.remove('uploadImgName42424198') }

原始数据 在这里插入图片描述 删除后 在这里插入图片描述

清空数据库的数据 const clearIndexDB = () => { imageDB.clearDB() } 更新数据

当前例子以imageName为主键

const updateIndexDB = () => { imageDB.update({ imageData: "uploadImgUrl", imageFile: "uploadFile", imageName: "uploadImgName33027705" }) } 查询数据 通过主键获取数据 // 从数据库获取数据 // imageName 可为空或者 null,即返回所有数据否则是指定key对应的值 const getImageByName = (imageName) => { imageDB.getDataByKey(imageName).then((res) => { console.log('从indexDB数据库获取数据成功', res) }).catch((err) => { console.log('从indexDB数据库获取数据失败==>', err) }) }

在这里插入图片描述

通过索引获取数据 const getDataByIndexDB = () => { imageDB.getDataByIndex({ index: 'imageData', value: 'uploadImgUrl57913099' }) }

在这里插入图片描述

关闭数据库 const closeIndexDB = () => { imageDB.closeDB() }

如下图,关闭数据库之后,再次获取数据会提示数据库已关闭,如果关闭后需要重新获取数据,则需执行imageDB.initDB() 打开数据库

在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有