首页 > 其他分享 >记录一下前端缓存分类汇总(indexDB、localStorage、sessionStorage)

记录一下前端缓存分类汇总(indexDB、localStorage、sessionStorage)

时间:2023-09-21 20:46:09浏览次数:39  
标签:function transaction sessionStorage 数据库 event localStorage var indexDB

什么是缓存?

当我们第一次访问网站的时候,比如 juejin.cn,电脑会把网站上的图片和数据下载到电脑上,当我们再次访问该网站的时候,网站就会从电脑中直接加载出来,这就是缓存。

缓存的优点和应用场景

Web缓存种类:indexDB、localStorage、sessionStorage。

  1. 缓解服务器压力,不用每次都去请求某些数据了。

  2. 提升性能,打开本地资源肯定会比请求服务器来得快。

  3. 减少带宽消耗,当我们使用缓存时,只会产生很小的网络消耗,至于为什么打开本地资源也会产生网络消耗,下面会有说明。

indexDB

介绍

首先indexDB是一个运行在浏览器的非关系型数据库,作为一个数据库,它存储的数据量就是没有上线的,同时它不仅可以存储字符串,还可以存储二进制数据。

主要特点

  1. 键值对存储:indexDB内部采用对象仓库存放数据。所有类型的数据都可以直接存入,包括Javascript对象。在仓库中,数据以键值对的形式进行保存,每一个数据记录都有对应的主键,且主键是独一无二的,不能有重复。
  2. 异步: indexDB操作时是异步操作,不会锁死浏览器,用户在操作indexDB数据库时,可同时进行其他操作(页面渲染等),相比于localStorage的同步操作相比,有利于在大量数据进行读写操作时,避免影响网页的性能。
  3. 支持事务:IndexDB支持事务,支持在数据库操作失败后,整个事务取消,数据库会回滚到之前的状态,有利于保证数据的安全与完整性。
  4. 同源限制:IndexDB收到同源限制,每一个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能跨域访问。
  5. 支持二进制储存:IndexDB不仅可以存储字符串,还可以储存二进制树(ArrayBuffer对象和Blob对象)。
  6. 储存空间大:indexDB由于是数据库,所以存储量比一般方式要大很多,一般来说不少于250MB。

基本概念

  1. 数据库(IDBDatabase对象):数据库是一系列相关数据的容器。每个域名(严格的说,是协议+域名+端口)都可以新建任意多个数据库,但他的版本的概念,同一时刻,只能有一个版本的数据库存在。如果要修改数据库结构(新增或删除表、索引或主键),只能通过升级数据库版本完成。
  2. 对象仓库(IDBObjectStore对象)每个数据库包含若干个对象仓库。它类似于关系型数据库的表格。
  3. 索引(IDBIndex):为了加速数据的检索可以在对象仓库里面,为不同的属性建立索引。
  4. 事务(IDTransaction对象):数据记录的读写和删除,都要通过事务完成。对象提供error、abort和complete三个监听事件监听操作结果。
  5. 操作请求(IDBRequest对象)。
  6. 指针(IDBCursor对象)。
  7. 主键集合(IDBKeyRange对象)。

代码示列

定义数据库初始变量

var db = null;
var db_table = null;
var databaseName = 'indexDB';
var version = 1;
var tableData = [{  //待存入数据
      id:1,
      name:'张一',
      age:  1,
      address:'西安'
  }]

打开数据库

/*
*@databaseName 数据仓库的名字
*@version 数据仓库的版本
*/
window.indexDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; //获取浏览器支持的indexDB数据库
var request = window.indexedDB.open(databaseName, version);
 
/*
*数据仓库打开失败
*/
request.onerror = function (error){
     console.log('IndexDB打开失败',error);
}
 
/*
*数据仓库打开成功
*/
request.onsuccess = function (res){
     db = res.target.result; //打开成功后用变量db存储数据库对象
}
 
/*
*数据仓库升级事件(第一次新建库是也会触发,因为数据仓库从无到有算是升级了一次)
*/
request.onupgradeneeded = function (res){
     db = res.target.result;
     //在数据库中创建表group,设置主键为id
     db_table = db.createObjectStore('tableA', { keyPath: 'id' });  
     //创建索引indexName指向表中的name字段且设为唯一值,不能重复
     db_table.createIndex('indexName', 'name', { unique: false });
}

存储数据

  • 写入数据需要新建一个事务,新建时必须指定表格名称和操作模式
/*
*新建事务
*@params 数据仓库的数组
*@params 写入模式,readwrite写入操作,为空时表示只读
*@objectStore对应数据库中的表
*/
var store = db.transaction(['tableA'], 'readwrite').objectStore('tableA');

/*
*add方法添加数据
*@params 需要添加的数据信息
*/
var transaction = store.add(tableData);//将上面创建的数据加入数据库
/*
*添加成功
*/
transaction.onsuccess = function (event) {
    console.log('数据添加成功',event);
};
/*
*添加失败
*/
transaction.onerror = function (event) {
    console.log('数据添加失败',event);
};

读取数据

  • 读取数据也是通过事务完成的
/*
*新建事务
*@params 数据仓库的数组
*/
var store = db.transaction(['tableA']).objectStore('tableA');

/*
*get方法获取数据
*@params 数据的主键
*/
var transaction = store.get(1); 
/*
*获取成功
*/
transaction.onsuccess = function (event) {
    if(event.target.result){
        console.log('数据获取成功',event);
    }
    else{
        console.log('未获取到数据');
    }
};

/*
*获取失败
*/
transaction.onerror = function (event) {
    console.log('数据获取失败',event);
};

更新表中的数据

  • 更新数据要使用 IDBObject.put()方法
/*
*新建事务
*@params 数据仓库的数组
*@params 写入模式
*/
var store = db.transaction(['tableA']).objectStore('tableA');
/*
*put方法根据主键更新数据
*@params 数据的主键
*/
var transaction = store .get(1);

transaction.onsuccess = function(event){
	let oldData = event.target.result
	oldData.age = 30
	const update = store.put(oldData)
	update.onerror=function(err){
		console.log(err)
	}
	update.onsuccess = function(event){
		console.log('完成更新')
	}
}

删除数据

var transaction = db.transaction(["tableA"], "readwrite")
                .objectStore("tableA")
                .delete("1");//按主键删除
transaction.onsuccess = function(event) {
  // It's gone!
};
transaction.onerror = function(event) {
  // It's gone!
};

使用索引

/*
*新建事务
*@params 数据仓库的数组
*/
var store = db.transaction(['tableA']).objectStore('tableA');

/*
*index方法获取索引对象
*get方法获取数据
*@params 数据的索引
*/
var request = store.index('indexName').get('张四'); 

/*
*获取成功
*/
request.onsuccess = function (event) {
     console.log('通过索引获取数据成功',event);
};

/*
*获取失败
*/
request.onerror = function (event) {
    console.log('通过索引获取数据失败',event);
};

使用指针遍历表中的所有值


var objectStore = db.transaction("tableA").objectStore("tableA");

objectStore.openCursor().onsuccess = function(event) {
  var cursor = event.target.result;
  if (cursor) {
    console.log("Name for SSN " + cursor.key + " is " + cursor.value.name);
    cursor.continue();
  }
  else {
    console.log("No more entries!");
  }
};

//另一种遍历方式
objectStore.getAll().onsuccess = function(event) {
  console.log("Got all objects" + event.target.result);
};
  • 限定函数范围介绍(截图自MDN官方文档)
    image
  • 指定光标的范围和方向
/*
*openCursor参数
*params1 用来控制指针显示的范围,为null时不做任何限制
*@params2 表示指针遍历的的方向
	"next": 光标显示所有记录,包括重复记录。它从键范围的下限开始向上移动(按键的顺序单调递增)。
	"nextunique": 光标显示所有记录,不包括重复记录。如果存在多个具有相同键的记录,则仅检索第一个迭代的记录。它从键范围的下限开始向上移动。
	"prev": 光标显示所有记录,包括重复记录。它从键范围的上限开始向下移动(按键的顺序单调递减)。
	"prevunique": 光标显示所有记录,不包括重复记录。如果存在多个具有相同键的记录,则仅检索第一个迭代的记录。它从键范围的上限开始向下移动。
*/
var index = objectStore.index("indexName");
const range = IDBKeyRange.bound(1,10);//遍历id从1到10的数据
index.openCursor(boundKeyRange).onsuccess = function(event) {
  var cursor = event.target.result;
  if (cursor) {
    cursor.continue();
  }
};

实际使用(localForage)

什么是 localForage

localForage 是一个 JavaScript 库,通过简单类似 localStorage API 的异步存储来改进你的 Web 应用程序的离线体验。它能存储多种类型的数据,而不仅仅是字符串。

localForage 有一个优雅降级策略,若浏览器不支持 IndexedDB 或 WebSQL,则使用 localStorage。在所有主流浏览器中都可用:Chrome,Firefox,IE 和 Safari(包括 Safari Mobile)。

安装

npm install localforage

API 使用

localForage 提供回调 API 同时也支持 ES6 Promises API.

回调 API 形式

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
  });
});

ES6 Promises 形式

localforage.setItem('key', 'value').then(function () {
  return localforage.getItem('key');
  }).then(function (value) {
    // we got our value
  }).catch(function (err) {
    console.log(err);
});

或使用 async / await 形式

try {
    const value = await localforage.getItem('somekey');
    console.log(value);
} catch (err) {
    console.log(err);
}

多个实例

createInstance 创建并返回一个 localForage 的新实例。每个实例对象都有独立的数据库,而不会影响到其他实例

var store = localforage.createInstance({
  name: "nameHere"
});

var otherStore = localforage.createInstance({
  name: "otherName"
});

// 设置某个数据仓库 key 的值不会影响到另一个数据仓库
store.setItem("key1", "value1");
otherStore.setItem("key2", "value2");

image

总结

在indexDB中,可以创建多个数据库,数据库中可以创建多张表,每张表中可以存储多条数据,当需要存储的数据复杂度高且数据量大时建议使用indexDB。

localStorage

  • localStorage可以实现永久存储,即使浏览器关闭了数据依然存在,在下次打开浏览器访问网站时仍然可以使用。而且在同源下数据多窗口状态也能共享。但是大多数浏览器限制localStorage的的大小为5M左右。
  • localStorage存储数据也是以键值对的形式进行保存的,且任何格式在存储时都会转为字符串格式。

用法

//保存数据
loaclStorage.setItem('name','whyweplay')
loaclStorage.setItem('name','whyweplay123') //重复对一个键进行赋值时会覆盖上一次保存的值

//读取数据
const name = localStorage.getItem('name')

//删除数据
localStorage.removeItem('name')

//清除localStorage中的全部数据
localStorage.clear()

//获取localStorage中的键
localStorage.key(index) //index表示第几个存入localStorage

//监听localStorage的的变化,当键值改变或clear()时会触发

window.addEventListener('storage', wacthHandler, false)
const watchHandler = function(e){
	console.log('监听到新值为'+e.newValue)
}

sessionStorage

  • sessionStorage与localStorage功能基本一致,区别是sessionStorage里面的数据会在页面会话结束时被清除。在打开多个相同页面的url的Tabs页面,会创建各自的sessionStorage。

用法

// 保存数据到 sessionStorage
sessionStorage.setItem('key', 'value');

// 从 sessionStorage 获取数据
let data = sessionStorage.getItem('key');

// 从 sessionStorage 删除保存的数据
sessionStorage.removeItem('key');

// 从 sessionStorage 删除所有保存的数据
sessionStorage.clear();

标签:function,transaction,sessionStorage,数据库,event,localStorage,var,indexDB
From: https://www.cnblogs.com/guozhiqiang/p/17720872.html

相关文章

  • 歌手页面收藏功能之本地存储localstorage之save
    收藏功能:一、本地存储代码,array-storage.js:importstoragefrom'good-storage' functioninsertArray(arr,val,compare){ constindex=arr.findIndex(compare) if(index>-1){  //index>-1说明val在arr中存在  return } arr.unshift(val)......
  • 20230829-sessionStorage实现数据的增删改查
    sessionStorage实现数据的增删改查#sessionStorage实现数据的增删改查(sessionStorage的方法对比localstorage)<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=......
  • 220230825-localstorage实现数据的增删改查
    演示案例<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document</title>......
  • localstorage实现数据的增删改查
    演示案例<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document</title>......
  • localstorage本地存储及token,vuex刷新数据丢失问题⚡⚡⚡
    1.vuex和axios安装,引入,使用1.1vuexa安装和使用vuex3.x版本的官网安装教程:安装|Vuexvuex4.x版本的官网安装教程:安装|Vuexnpminstallvuex--save2.在src下新建文件夹store,并在文件夹中新建文件index.js,如下:importVuexfrom'vuex'//引入user模块化modules......
  • 具备有效期的sessionStorage存储
    具备有效期的sessionStorage存储类方式//具备有效期的sessionStorage存储-类方式。classSessionStorageWrapper{//存储数据到sessionStorage,记录下当前存储的时间。staticsetItem(key,value){try{constitem={value,time:Date.......
  • 具备有效期的localStorage存储
    具备有效期的localStorage存储类方式//具备有效期的localStorage存储-类方式。classLocalStorageWrapper{//存储数据到localStorage,记录下当前存储的时间。staticsetItem(key,value){try{constitem={value,time:Date.now(),//......
  • cookie和localStorage和sessionStorage的区别
    cookie和localStorage和sessionStorage的区别下面从几个方向区分一下cookie,localStorage,sessionStorage的区别生命周期:cookie:可设置失效时间,否则默认为关闭浏览器后失效。localStorage:除非被手动清除,否则永久保存。sessionStorage:仅在当前网页会话下有效,关闭页面或关......
  • 前端之localStorage
    问题:同一个浏览器同时打开两个saas,发现localStorge共用同一个,相同key值的存储会相互覆盖原因:同一域名下,localStorage共享解决方法:不同saas使用不同的key下面介绍一下localStorage特性:1、永久存储,除非主动删除2、同一域名下可以多窗口共享3、键值对存储,方便管理使用:引入......
  • vue--day44-todolist的localStorage本地存储
    添加修改删除数据发生变化,可以用watch监测来实现监测数据的变化1.App.vue  <template><divid="root"><divclass="todo-container"><divclass="todo-wrap"><!--传递函数儿子给父亲传东西,父亲偷偷传递一个函数,儿子调用这个函数--><MyHeader:addTodo=&q......