indexedDB---掌握浏览器内建数据库的基本用法
1.认识indexedDB
IndexedDB 是一个浏览器内建的数据库,它可以存放对象格式的数据,类似本地存储localstore,但是相比localStore 10MB的存储量,indexedDB可存储的数据量远超过这个数值,具体是多少呢?
默认情况下,浏览器会将自身所在的硬盘位置剩余容量全部作为indexedDB的存储容量,


这里差不多就对应这c盘的剩余容量,所以indexDB有第一个特点,容量大;
存储的格式,以对象的键值形式存储数据,注意这里的 id 是一个唯一的索引属性,

在indexedDB中,需要有一个唯一的标识符来区分存储的内容,这里使用的是id,这表示,存储的每一个值内都需要一个唯一的id值,这是第二个特点,统一的唯一标识符(key),
最后它采用的是,对象存储库和存储表的数据存放方式;你可以理解成,indexedDB是一个大的数据对象(object),它内部包含了很多数据库(object),每个数据库内又有很多存储对象表(array),每个表内又有很多键值对(object),


在indexedDB中,有很多上面的这种存储库对象,可以看出这是一个树形结构,根节点就是indexedDB
所以,总结一下,indexedDB:
- 容量大
- 有唯一标识符(key)
- 树形结构的对象存储
- 和localStore一样同一个域名下的indexedDB是一致的,否则不一致,每个网页都有各自的indexedDB(补充)
2.indexedDB数据库的使用
查看indexedDB
我们可以在开发者工具中直接查看indexedDB数据库,也可以在控制台打印出来,indexedDB是window对象下的一个属性,
// 浏览器本地数据库
console.log(indexedDB);// window.indexedDB

打开数据库
const request = indexedDB.open(name, version);name —— 字符串,即数据库名称。
version —— 一个正整数版本,默认为 1。返回 openRequest 对象
注意:数据库的相关操作都是异步的,打开、读取和编辑、删除,都需要时间处理,并不是马上执行结束,所以每一个对数据库的相关操作都有回调事件进行监听,
success:打开成功,数据库准备就绪 ,request.result中有了一个数据库对象“Database Object”,这就是一个数据库,我们可以通过它访问这个库的所有数据error:打开失败。upgradeneeded:更新版本,当数据库的版本更新时触发,例如,1->2。
这里解释一下版本号,一个 数据库在打开时,若没有这个库,则会新建,默认版本号为1;若有,打开时的版本号比原本保存的版本号更高,则会更新这个库,同时触发upgradeneeded事件,一个数据库的版本号只会越来越高,不会出现还原旧版本的情况,这是因为有些特定的操作只能在版本更新时执行(upgradeneeded事件)--- 例如,新建、编辑、删除一个对象存储表
// 浏览器本地数据库
console.log(indexedDB);// window.indexedDB// 打开数据库
const request = indexedDB.open('myDatabase', 1);request.onerror = function(event) {console.error('数据库打开报错');
}request.onupgradeneeded = function(event) {const db = event.target.result;console.log('数据库需要升级');// 创建一个对象存储空间
}request.onsuccess = function(event) {const db = event.target.result;console.log('数据库打开成功');
}


新建了一个myDatabase数据库,触发 了一次版本更新,在次执行时版本还是1就不会触发更新升级的事件,

这样就成功新建、打开了一个数据库,
新建一个对象存储表
db.createObjectStore(name[, keyOptions]);name 是存储区名称,例如 "books" 表示书。
keyOptions 是具有以下两个属性之一的可选对象:keyPath —— 对象属性的路径,IndexedDB 将以此路径作为键,例如 id。autoIncrement —— 如果为 true,则自动生成新存储的对象的键,键是一个不断递增的数字。
- name:储存表的名称
- keyOptions: 配置对象,
- keyPath: 储存数据的标识符
- autoIncrement:默认为false,若为true,则会自动在储存的对象上添加标识符属性,并附上一个自增的正数值(1,2,3,4......)
要操作对象存储表就需要更新版本号,这个createObjectStore方法只能在更新事件内使用,否则将产生错误
// 打开数据库
const request = indexedDB.open('myDatabase', 2);request.onupgradeneeded = function(event) {const db = event.target.result;console.log('数据库需要升级');// 创建一个对象存储空间db.createObjectStore('imgStore', { keyPath: 'id', autoIncrement: true });console.log('对象存储表创建成功');
}request.onsuccess = function(event) {const db = event.target.result;console.log('数据库打开成功');
}


注意需要增加版本号,否则不触发更新事件,这里新建了一个叫imgStore的对象存储表
添加和读取数据
添加和读取数据都在onsuccess的回调中执行,不需要更新版本,
添加数据add()---参数any
request.onsuccess = function(event) {const db = event.target.result;console.log('数据库打开成功');// 连接数据库的表,比获取读写权限,默认只读const transaction = db.transaction(['imgStore'], 'readwrite');const objectStore = transaction.objectStore('imgStore');// 添加数据const re = objectStore.add({name: 'test',content:'测试数据'});re.onsuccess = function (event) {console.log('文件添加成功');}
}
transaction是一个事务,连接了imgStore,并开放读写权限,之后再通过事务,获取imgStore对象存储表,最后再执行add添加数据,这里添加了一个测试对象,同样添加时一个异步操作,需要回调等待结果,


这里成功添加后可以查看数据表中的内容,如果内容没有出现可以 点击刷新,看到结果后可以发现,多了一个属性id,这个就是存储对象的标识符,前面设置了自动添加,若没有设置自动添加,则需要手动的添加一个id属性,且id的值不能和其他数据相同,否则都会添加失败
读取数据get()---参数标识符的值
request.onsuccess = function(event) {const db = event.target.result;console.log('数据库打开成功');// 连接数据库的表,比获取读写权限,默认只读const transaction = db.transaction(['imgStore'], 'readwrite');const objectStore = transaction.objectStore('imgStore');// // 添加数据// const re = objectStore.add({// name: 'test',// content:'测试数据'// });// re.onsuccess = function (event) {// console.log('文件添加成功');// }// 读取数据const re2 = objectStore.get(1);re2.onsuccess = function (event) {console.log(re2.result);}
}

可以看到成功读取到了id为1的数据,
示例:存储一张图片
了解了添加和读取数据,那我们可以来实现上传一张图片,保存再数据库中,
思路:通过input file 上传一个图片,再将其存为blob,再将blob转成base64存储起来
(有关blob的操作可以参考:js二进制数据,文件---blob对象_js 输出 blob-CSDN博客)
let addFile;request.onsuccess = function (event) {const db = event.target.result;console.log('数据库打开成功');addFile = function (file) {// 连接数据库的表,比获取读写权限,默认只读const transaction = db.transaction(['imgStore'], 'readwrite');const objectStore = transaction.objectStore('imgStore');const re = objectStore.add(file)re.onsuccess = function (event) {console.log('文件添加成功');}}
}const file = document.getElementById('file');
file.addEventListener('change', (event) => {const file = event.target.files[0];if (file.type == 'image/jpeg') { // 如果文件是图片let blob = new Blob([file], { type: 'image/jpeg' });let reader = new FileReader();reader.readAsDataURL(blob);reader.onload = function (event) {let base64 = event.target.result;console.log(base64);addFile({name: file.name,data: base64})}}
})


这样我们就成功存放了一个base64形式的图片文件,
然后我们可以读取出这个图片,渲染再页面上
request.onsuccess = function (event) {const db = event.target.result;console.log('数据库打开成功');let getFile = function(){// 连接数据库的表const transaction = db.transaction(['imgStore'], 'readonly');const objectStore = transaction.objectStore('imgStore');// 获取数据const re = objectStore.get(1);re.onsuccess = function (event) {console.log(re.result);let img = new Image();img.src = re.result.data;img.width=800;document.body.appendChild(img);}}getFile()
}

这样就成功拿到了图片,并且每次刷新后都会保留这个图片,就相当于一个能放大文件的localStore
完整代码展示
index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>本地数据库</title>
</head>
<body><input type="file" name="" id="file"></body>
<script src="index.js"></script>
</html>
index.js
// 浏览器本地数据库
console.log(indexedDB);// window.indexedDB
let addFile;//添加文件的方法
// 打开数据库
const request = indexedDB.open('myDatabase', 2);request.onerror = function (event) {console.error('数据库打开报错');
}request.onupgradeneeded = function (event) {const db = event.target.result;console.log('数据库需要升级');// 创建一个对象存储空间db.createObjectStore('imgStore', { keyPath: 'id', autoIncrement: true });console.log('对象存储表创建成功');
}request.onsuccess = function (event) {const db = event.target.result;console.log('数据库打开成功');// // 连接数据库的表,获取读写权限,默认只读// const transaction = db.transaction(['imgStore'], 'readwrite');// const objectStore = transaction.objectStore('imgStore');// // 添加数据// const re = objectStore.add({// name: 'test',// content:'测试数据'// });// re.onsuccess = function (event) {// console.log('文件添加成功');// }// 读取数据// const re2 = objectStore.get(1);// re2.onsuccess = function (event) {// console.log(re2.result);// }addFile = function (file) {// 连接数据库的表,获取读写权限,默认只读const transaction = db.transaction(['imgStore'], 'readwrite');const objectStore = transaction.objectStore('imgStore');const re = objectStore.add(file)re.onsuccess = function (event) {console.log('文件添加成功');}}let getFile = function(){// 连接数据库的表const transaction = db.transaction(['imgStore'], 'readonly');const objectStore = transaction.objectStore('imgStore');// 获取数据const re = objectStore.get(1);re.onsuccess = function (event) {console.log(re.result);let img = new Image();img.src = re.result.data;img.width=800;document.body.appendChild(img);}}getFile()
}const file = document.getElementById('file');
file.addEventListener('change', (event) => {const file = event.target.files[0];if (file.type == 'image/jpeg') { // 如果文件是图片let blob = new Blob([file], { type: 'image/jpeg' });let reader = new FileReader();reader.readAsDataURL(blob);reader.onload = function (event) {let base64 = event.target.result;console.log(base64);addFile({name: file.name,data: base64})}}
})
相关文章:
indexedDB---掌握浏览器内建数据库的基本用法
1.认识indexedDB IndexedDB 是一个浏览器内建的数据库,它可以存放对象格式的数据,类似本地存储localstore,但是相比localStore 10MB的存储量,indexedDB可存储的数据量远超过这个数值,具体是多少呢? 默认情…...
【css】如何修改input选中历史选项后,自动填充的蓝色背景色
自动填充前: 自动填充后: 解决办法 方法一:设置背景透明(通过拉长过渡时间,和延迟过渡开始时间,掩盖input自动填充背景颜色) PS:注意,这个过渡效果会在你的delay tim…...
红队内网攻防渗透:内网渗透之内网对抗:网络通讯篇防火墙组策略入站和出站规则单层双层C2正反向上线解决方案
红队内网攻防渗透 1. 内网网络通讯1.1 防火墙策略-入站规则&出站规则&自定义1.1.1 防火墙默认入站&出站策略1.1.2 防火墙自定义入站&出站策略1.1.3 内网域防火墙同步策略1.2 防火墙限制1.2.1 防火墙限制端口1.2.2 防火墙限制协议1.2.2.1 防火墙协议入站限制1.2…...
linux 查看进程启动方式
目录 如果是systemd管理的服务怎么快速找到对应的服务器呢 什么是CGroup 查找进程对应的systemd服务 方法一:查看 /proc//cgroup 文件 方法二:使用 ps 命令结合 --cgroup 选项 方法三:systemd-cgls 关于 system.slice 与 user.slice …...
基于Java实训中心管理系统设计和实现(源码+LW+调试文档+讲解等)
💗博主介绍:✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 🌟文末获取源码数据库🌟 感兴趣的可以先收藏起来,…...
第2章 Android应用的界面编程
🌈个人主页:小新_- 🎈个人座右铭:“成功者不是从不失败的人,而是从不放弃的人!”🎈 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝 🏆所属专栏࿱…...
springboot学习-图灵课堂-最详细学习
springboot-repeat springBoot学习代码说明为什么java -jar springJar包后项目就可以启动 配置文件介绍 springBoot学习 依赖引入 <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.target>8</mav…...
Total CAD Converter与Total Excel Converter软件分享
1.软件介绍 Total CAD Converter Total CAD Converter 是一款功能强大的工具,能够将 CAD 文件转换为多种格式,如 PDF、TIFF、JPEG、BMP、WMF、PNG、DXF、BMP、CGM、HPGL、SVG、PS 和 SWF 等。其支持的源格式丰富多样,包括 dxf、dwg、dwf、d…...
【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 启动多任务排序(200分) - 三语言AC题解(Python/Java/Cpp)
🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 启动多任务排序(200分) 🌍 评测功能需要订阅专栏后私信联系…...
【会议征稿,JPCS出版】第三届电力系统与能源技术国际学术会议(ICPSET 2024,7月5-7)
第三届电力系统与能源技术国际学术会议(ICPSET 2024)将于2024年7月5-7日在杭州举办。由浙江水利水电学院电机产业学院主办,AEIC学术交流中心承办,湖州市南浔创新研究院、南浔区科技局(科协)协办 。会议主要…...
【机器学习300问】118、循环神经网络(RNN)的基本结构是怎样的?
将讲解循环神经网络RNN之前,我先抛出几个疑问:为什么发明循环神经网络?它的出现背景是怎样的?这些问题可以帮助我们更好的去理解RNN。下面我来逐一解答。 一、循环神经网络诞生的背景 循环神经网络(RNN)的…...
loveqq-framework 和 thymeleaf 整合遇到的 th:field 的坑,原来只有 spring 下才有效
相信大家在使用 thymeleaf 的时候,绝大部分都是和 springboot 一块儿使用的,所以 th:field 属性用的很舒服。 但实际上,th:field 只有在 spring 环境下下有用,单独的 thymeleaf 是不支持的! 为什么我知道呢ÿ…...
hugging face:大模型时代的github介绍
1. Hugging Face是什么: Hugging Face大模型时代的“github”,很多人有个这样的认知,但是我觉得不完全准确,他们相似的地方在于资源丰富,github有各种各样的软件代码和示例,但是它不是系统的,没…...
如何快速绘制logistic回归预测模型的ROC曲线?
临床预测模型,也是临床统计分析的一个大类,除了前期构建模型,还要对模型的预测能力、区分度、校准度、临床获益等方面展开评价,确保模型是有效的! 其中评价模型的好坏主要方面还是要看区分度和校准度,而区分…...
实现具有多个实现类的接口并为每个实现类定义一个名字的方法
在Java中,实现具有多个实现类的接口并为每个实现类定义一个名字的方法,可以通过使用工厂模式或服务定位器模式来完成。以下是使用工厂模式的一个示例: 定义接口和实现类 首先,定义一个接口和多个实现类: // 接口 publ…...
Linux解压缩命令
文章目录 前言1. tar - 打包和压缩文件2. gzip - 压缩文件3. gunzip - 解压缩gzip文件4. bzip2 - 压缩文件5. unzip - 解压缩zip文件6. zip - 压缩文件为zip格式7. 7z - 7-Zip压缩工具8. unrar - 解压缩RAR文件 前言 解压缩文件在Linux中是常见的任务,以下是一些常…...
如何在 Ubuntu 14.04 上使用 Iptables 实现基本防火墙模板
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 简介 实施防火墙是保护服务器的重要步骤。其中很大一部分是决定强制执行对网络流量的限制的个别规则和策略。像 iptables 这样的防火墙…...
jasypt对yml文件进行加密解密
目录 0.背景 1.依赖 2.yml文件 3.加密操作 0.背景 在日常开发中,我们一般会把账号密码以及一些用到的各种第三方服务的Access_Key都放入yml文件中,这时就有必要对yml文件进行加密处理了, jasypt是一款简单的对yml加密的工具 1.依赖 &l…...
vue3-openlayers 使用tianditu,wmts和xyz等source加载天地图切片服务
本篇介绍一下使用vue3-openlayers加载天地图切片,三种方法: 使用tianditu(ol-source-tianditu内部实现其实用的wmts)使用wmts(ol-source-wmts)使用xyz(ol-source-xyz) 1 需求 vue…...
npm、yarn、pnpm 最新国内镜像源设置和常见问题解决
1. npm 设置国内镜像源 1.1 镜像源概述 镜像源是软件包管理工具用来下载和安装软件包的服务器地址。由于网络原因,直接使用官方源可能会导致速度慢或连接失败的问题。国内镜像源可以提供更快的访问速度和更稳定的连接。 1.2 镜像源的选择 国内有许多可用的npm镜…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...
数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...
