当前位置: 首页 > news >正文

JavaScript 第19章:Web Storage

在JavaScript中,Web存储(Web Storage)提供了一种在用户浏览器中持久化数据的方式。这里我们会探讨localStoragesessionStorage以及IndexedDB,并提供一些简单的示例代码来展示它们的用法。

localStorage

localStorage允许你在用户的浏览器中存储键值对数据,这些数据会一直保存,除非用户清除了浏览器的数据或开发者手动删除了这些数据。

示例代码:
// 存储数据
localStorage.setItem('name', 'John Doe');// 获取数据
let name = localStorage.getItem('name');
console.log(name); // 输出 "John Doe"// 删除数据
localStorage.removeItem('name');

sessionStorage

localStorage类似,sessionStorage也是用来存储键值对数据,但是它仅在当前浏览器窗口或标签页的生命周期内有效。当用户关闭所有属于该站点的窗口或标签页时,这些数据会被清除。

示例代码:
// 存储数据
sessionStorage.setItem('sessionName', 'Jane Doe');// 获取数据
let sessionName = sessionStorage.getItem('sessionName');
console.log(sessionName); // 输出 "Jane Doe"// 删除数据
sessionStorage.removeItem('sessionName');

IndexedDB

IndexedDB是一个客户端数据库系统,允许存储大量的结构化数据,并且可以搜索索引。它适合存储比简单键值对更复杂的数据结构,如对象或二进制大对象(BLOBs)等。

示例代码:
let db;
const request = window.indexedDB.open('myDatabase', 1);request.onerror = function(event) {console.log('Error opening IndexedDB database.');
};request.onsuccess = function(event) {db = event.target.result;console.log('Database opened successfully.');
};request.onupgradeneeded = function(event) {let db = event.target.result;let objectStore = db.createObjectStore('users', {keyPath: 'id'});objectStore.createIndex('name', 'name', {unique: false});
};function addData() {let transaction = db.transaction(['users'], 'readwrite');let objectStore = transaction.objectStore('users');let newUser = {id: 1, name: 'Alice'};objectStore.add(newUser);
}function getData() {let transaction = db.transaction(['users'], 'readonly');let objectStore = transaction.objectStore('users');let request = objectStore.get(1);request.onsuccess = function(event) {let data = event.target.result;console.log(data);};
}

以上代码展示了如何创建一个名为myDatabase的数据库,并且包含了一个名为users的对象存储区(object store)。我们还定义了如何添加和检索数据的方法。注意,IndexedDB的操作通常是在异步事件处理程序中完成的。

这些例子只是基本的使用方法,实际应用中可能需要更复杂的错误处理逻辑以及事务管理。

IndexedDB 进阶示例

让我们扩展前面的例子,增加更多功能,比如更新数据、删除数据、遍历数据等。

更新数据

更新数据涉及到获取现有记录,修改它,然后将其放回存储中。

function updateData(id, updatedUser) {let transaction = db.transaction(['users'], 'readwrite');let objectStore = transaction.objectStore('users');objectStore.put(updatedUser);
}

在这个例子中,我们直接使用put方法来更新数据。如果提供的对象的键已经存在于对象存储中,则此操作将替换现有的条目。

删除数据

删除特定记录可以通过其主键来实现。

function deleteData(id) {let transaction = db.transaction(['users'], 'readwrite');let objectStore = transaction.objectStore('users');objectStore.delete(id);
}
遍历所有数据

要获取对象存储中的所有数据,我们可以使用游标(cursor)。

function getAllData() {let transaction = db.transaction(['users'], 'readonly');let objectStore = transaction.objectStore('users');let request = objectStore.openCursor();request.onsuccess = function(event) {let cursor = event.target.result;if (cursor) {console.log(cursor.key + ": " + JSON.stringify(cursor.value));cursor.continue();}};
}

这个函数会打印出对象存储中的每一项记录的键和值。

错误处理

在处理IndexedDB操作时,必须考虑错误处理。例如,在打开数据库时可能会失败,或者在事务执行过程中可能会遇到其他错误。

request.onerror = function(event) {console.error('An error occurred with the indexedDB request.');
};transaction.onerror = function(event) {console.error('An error occurred with the transaction.');
};

总结

IndexedDB是一个非常强大的API,它允许在客户端进行复杂的数据存储和检索。虽然它的API比localStoragesessionStorage要复杂得多,但这也意味着它可以处理更加复杂的应用场景。为了有效地使用IndexedDB,你需要熟悉事务、游标、对象存储、索引等概念。

以上示例提供了一个基本框架来开始使用IndexedDB。在实际项目中,你可能还需要考虑更多高级特性,例如版本控制、事务回滚、并发控制等。

版本控制

当你的应用程序需要更改已存在的数据库结构时(例如添加新的对象存储、改变键路径、添加索引等),需要通过版本控制来管理这些更改。当打开数据库时,如果提供了新的版本号并且旧版本仍然存在,那么会触发onupgradeneeded事件。

request.onupgradeneeded = function(event) {let db = event.target.result;if (!db.objectStoreNames.contains('users')) {db.createObjectStore('users', { keyPath: 'id' });}let usersStore = db.transaction.objectStore('users');if (!usersStore.indexNames.contains('name')) {usersStore.createIndex('name', 'name', { unique: false });}
};

在这个例子中,我们检查是否存在users对象存储,并且检查是否存在name索引。如果不存在,则创建它们。

事务的回滚

在某些情况下,你可能希望在事务失败时回滚事务。这通常是通过设置事务的oncompleteonerror事件处理器来实现的。

let transaction = db.transaction(['users'], 'readwrite');
transaction.oncomplete = function(event) {console.log('Transaction completed.');
};
transaction.onerror = function(event) {console.error('Transaction failed.');transaction.rollback();
};

在这个例子中,如果事务失败,将会记录错误信息并且回滚事务。

并发控制

IndexedDB支持多窗口或多标签页同时访问同一个数据库。为了防止数据冲突,IndexedDB使用锁定机制来确保在任何时刻只有一个事务可以修改一个给定的对象存储。

如果你的应用程序需要支持多个窗口之间的协调工作,你可能需要实现额外的逻辑来处理并发情况。例如,可以在事务开始前检查数据的状态,或者在事务提交后通知其他窗口数据已更改。

数据类型

IndexedDB支持多种数据类型,包括字符串、数字、日期、数组、对象等。然而,需要注意的是,某些类型的数据(如函数、undefined、Symbol等)不能直接存储在IndexedDB中。对于复杂对象,确保它们是可序列化的,并且在存储之前转换为JSON格式。

let user = {id: 1,name: 'John Doe',birthDate: new Date(),tags: ['developer', 'musician']
};objectStore.put(user);

性能优化

尽管IndexedDB非常强大,但在处理大量数据时,性能可能会成为一个问题。以下是一些提高性能的技巧:

  1. 使用索引:为频繁查询的属性创建索引。
  2. 批量操作:尽量使用事务来批量处理多个读写操作。
  3. 限制大小:避免存储过大的对象或过多的数据,这可能会导致内存和性能问题。

我们将继续探讨IndexedDB的一些实际应用和最佳实践,包括如何处理大数据量、如何进行数据迁移以及如何使用索引来提高查询效率。

处理大数据量

当IndexedDB用于存储大量数据时,性能和内存管理变得尤为重要。以下是一些处理大数据量的策略:

  1. 分批处理:当需要插入或更新大量数据时,可以将数据分成小批次进行处理。这样可以减少单个事务的负载,从而提高整体性能。

    function batchAddUsers(users, batchSize) {let count = 0;let transaction = db.transaction(['users'], 'readwrite');let objectStore = transaction.objectStore('users');for (let user of users) {if (count % batchSize === 0) {transaction.oncomplete = function() {transaction = db.transaction(['users'], 'readwrite');objectStore = transaction.objectStore('users');};}objectStore.add(user);count++;}
    }
    
  2. 垃圾回收:IndexedDB有一个内部的垃圾回收机制,可以自动清理不再使用的空间。但是,如果你知道某个对象存储不再需要,可以显式地删除它以释放空间。

    db.deleteObjectStore('obsoleteStore');
    

数据迁移

当应用程序需要对数据库结构进行重大更改时,数据迁移就变得很重要。在onupgradeneeded事件中,你可以编写代码来处理数据迁移。

request.onupgradeneeded = function(event) {let db = event.target.result;if (event.oldVersion < 2) {db.createObjectStore('newUsers', { keyPath: 'id' });let transaction = db.transaction(['users'], 'readwrite');transaction.oncomplete = function() {db.close(); // 关闭旧数据库连接};let usersStore = transaction.objectStore('users');let newUsersStore = db.transaction('newUsers').objectStore('newUsers');usersStore.openCursor().onsuccess = function(event) {let cursor = event.target.result;if (cursor) {let newUser = Object.assign({}, cursor.value); // 复制旧用户数据newUsersStore.add(newUser);cursor.delete(); // 删除旧数据cursor.continue();}};}
};

在这个例子中,我们在新版本中创建一个新的对象存储,并从旧的存储中迁移数据。

使用索引提高查询效率

索引可以大大提高查询效率,尤其是在需要根据非主键字段进行查找的情况下。创建索引后,可以通过索引进行查询。

let objectStore = db.createObjectStore('users', { keyPath: 'id' });
objectStore.createIndex('name', 'name', { unique: false });// 查询名为 "Alice" 的用户
function findUserByName(name) {let index = db.transaction('users', 'readonly').objectStore('users').index('name');let request = index.get(name);request.onsuccess = function(event) {let user = event.target.result;console.log(user);};
}

安全性

在使用IndexedDB时,还需要考虑安全性。虽然IndexedDB本身是安全的,因为它只在客户端运行并且每个域名/协议组合都有自己的隔离存储空间,但你仍需小心处理敏感数据。

  1. 避免存储敏感信息:尽可能不要在IndexedDB中存储密码或其他敏感信息。
  2. 使用HTTPS:使用HTTPS来保护通信安全,防止中间人攻击。

结论

通过上述示例和建议,你应该能够更好地理解和使用IndexedDB来构建高性能的Web应用程序。如果你有特定的需求或问题,欢迎继续提问!

相关文章:

JavaScript 第19章:Web Storage

在JavaScript中&#xff0c;Web存储&#xff08;Web Storage&#xff09;提供了一种在用户浏览器中持久化数据的方式。这里我们会探讨localStorage、sessionStorage以及IndexedDB&#xff0c;并提供一些简单的示例代码来展示它们的用法。 localStorage localStorage允许你在用…...

[山河2024] week2

官方WP出得很快。对照官的写下私的。大概出入不大&#xff0c;毕竟第2周。后边的才难。 Crypto E&R RSA因子分解题&#xff0c;把q的2进制反转后与p异或。关于异或的题很多&#xff0c;这个还真是头一回见&#xff0c;不过爆破方法还是一样的。 r_q int(bin(q)[2:][::…...

无限可能LangChain——开启大模型世界

什么是大语言模型&#xff1f; 大语言模型是一种人工智能模型&#xff0c;通常使用深度学习技术&#xff08;如神经网络&#xff09;来理解和生成人类语言。这些模型拥有非常多的参数&#xff0c;可以达到数十亿甚至更多&#xff0c;使得它们能够处理高度复杂的语言模式。 我…...

URL路径以及Tomcat本身引入的jar包会导致的 SpringMVC项目 404问题、Tomcat调试日志的开启及总结

一、URL路径导致的 SpringMVC项目 404问题 SpringMVC项目的各项代码都没有问题&#xff0c;但是在页面请求时仍然显示404&#xff0c;编译的时候报了下面的问题&#xff1a; org.apache.jasper.servlet.TldScanner.scanJars 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录…...

如何引起Java中的System.in.read()函数的异常

演示的为:关闭标准输入流System.in后再调用System.in.read就会报出IOException import java.io.IOException; import java.io.InputStream;public class Test {public static void main(String[] args) {InputStream in System.in;try {in.close();System.in.read();}catch (…...

深入理解Flutter鸿蒙next版本 中的Widget继承:使用extends获取数据与父类约束

目录 写在前面 什么是Widget继承&#xff1f; 基本概念 StatelessWidget与StatefulWidget build方法 创建自定义Widget 1. 继承StatelessWidget 2. 继承StatefulWidget并访问父类的约束 3. 继承其他自定义Widget并获取数据 写在最后 写在前面 在Flutter中&#xff0c…...

Loss:Focal Loss for Dense Object Detection

目录 3. 焦点损失(Focal Loss)3.1. 平衡交叉熵3.2. 焦点损失定义3.3. 类别不平衡与模型初始化3.4. 类别不平衡与两阶段检测器4. RetinaNet 检测器。4.1. 推理与训练。3. 焦点损失(Focal Loss) 焦点损失(Focal Loss)旨在解决单阶段目标检测场景中训练时前景和背景类别之间…...

Unity3D中Excel表格的数据处理模块详解

前言 在Unity3D项目中&#xff0c;处理Excel表格数据是一项常见且重要的任务。通过Excel表格&#xff0c;我们可以方便地管理游戏配置、角色属性等数据内容。本文将详细介绍如何在Unity3D中实现Excel表格的数据处理模块&#xff0c;包括技术详解和代码实现。 对惹&#xff0c…...

【python】OpenCV—Fun Mirrors

文章目录 1、准备工作2、原理介绍3、代码实现4、效果展示5、参考 1、准备工作 pip install vacm2、原理介绍 在OpenCV中&#xff0c;VCAM 库是一个用于简化创建三维曲面、定义虚拟摄像机、设置参数以及进行投影任务的工具。它特别适用于实现如哈哈镜等图像变形效果。 一、VC…...

QT IEEE754 16进制浮点数据转成10进制

IEEE754标准转换QT代码 qtcreator使用的ieee754标准的4字节数组与浮点数之间的转换方法&#xff0c;ieee754的4位数组如果转换成二进制后&#xff0c;大体结构是&#xff1a; 位序号12-910-32意义 符号位&#xff0c; 正数为0&#xff0c;负数为1. 指数位&#xff0c; 指数是…...

无人机+视频推流直播EasyCVR视频汇聚/EasyDSS平台在森林防护巡检中的解决方案

随着科技的飞速发展&#xff0c;无人机技术在各个领域的应用日益广泛&#xff0c;特别是在森林防护与巡检方面&#xff0c;无人机以其独特的优势&#xff0c;为传统林业管理带来了革命性的变化。本文将探讨无人机在森林防护巡检中的解决方案&#xff0c;分析其工作原理、优势及…...

Rancher—多集群Kubernetes管理平台

目录 一、Rancher 简介1.1 Rancher 和 k8s 的区别 二、Rancher 安装及配置2.1 安装 rancher2.2 登录 Rancher 平台2.3 Rancher 管理已存在的 k8s 集群2.4 创建名称空间 namespace2.5 创建 Deployment 资源2.6 创建 service2.7 Rancher 部署监控系统 一、Rancher 简介 Rancher …...

使用多IP香港站群服务器对网站管理seo优化提升排名有益处

在网站管理和优化中&#xff0c;选择合适的服务器是至关重要的。针对某些特定需求&#xff0c;使用多IP香港站群服务器可以带来明显的益处。本文将探讨使用多IP香港站群服务器 对网站管理的明显益处&#xff0c;并介绍其中的关键要点和优势。 I. 理解多IP香港站群服务器 1. 多I…...

网管平台(基础篇):网管系统的重要性

网管系统的核心地位&#xff1a;数字世界的稳定舵手 在信息技术日新月异的今天&#xff0c;网络如同一条无形的纽带&#xff0c;将世界紧密相连。然而&#xff0c;这条纽带背后隐藏着无数复杂的节点与链路&#xff0c;如何确保它们高效、稳定地运行&#xff0c;成为了一个亟待解…...

Ubuntu20.04下安装多CUDA版本,以及后续切换卸载

本方案的前提是假设机子上已经有一个版本的cuda&#xff0c;现在需要支持新的torch2.1.2和torchvision0.16.2&#xff0c;于是来安装新的cuda 一、选择版本 如果我想安装支持torch2.1.2的cuda版本&#xff0c;到官网&#xff08;https://pytorch.org/get-started/previous-ve…...

图像处理高频面试题及答案

目录 高频面试题及答案1. 什么是图像处理?2. 什么是图像的分辨率?3. 图像的颜色空间是什么?4. 什么是边缘检测,为什么重要?5. 解释一下图像增强的常见方法。6. 什么是图像的直方图?7. 什么是图像的去噪声?8. 什么是图像分割,常用的方法有哪些?9. 图像滤波的目的是什么…...

尤雨溪都打赏的虚拟列表组件,到底有多强

尤雨溪都打赏的虚拟列表组件&#xff0c;到底有多强&#xff1f; 在前端开发中&#xff0c;性能优化永远是绕不开的主题。今天就带你看看 vue-virtual-scroller&#xff0c;一款让你滚动页面时流畅得像火箭一样的 Vue 组件。本文将简单介绍这个组件的主要功能、技术特点&#x…...

FrameWork使用EfCore数据库映射举例

Microsoft.EntityFrameworkCore新的版本不支持FrameWork框架。 这里举例使用旧版本实现数据存取 首先下载 Microsoft.EntityFrameworkCore 版本控制在2.1.14以下 同样下载Microsoft.EntityFrameworkCore.sqlite 举例时间记录 public class RunTimeInfo{[Key]public int Id { g…...

汽车与航空领域的功能安全对比:ISO 26262-6 与 DO-178C 的差异浅析

ISO 26262-6 和 DO-178C &#xff08;航空系统与设备认证中的软件考量&#xff09;。是汽车和航空领域分别广泛应用的软件安全标准。它们的共同目标是确保系统软件可靠性&#xff0c;减少系统软件故障对生命安全的威胁&#xff0c;但在具体的软件安全方案和规范实施上存在明显的…...

linux命令之lspci用法

lspci 显示当前主机的所有PCI总线信息 补充说明 lspci命令 用于显示当前主机的所有PCI总线信息&#xff0c;以及所有已连接的PCI设备信息。 语法 lspci(选项)选项 -n&#xff1a;以数字方式显示PCI厂商和设备代码&#xff1b; -t&#xff1a;以树状结构显示PCI设备的层次…...

AI图文识别 VS 人类学习|后Transformer时代

AI怎么识别是哪部小说总结前置&#xff1a; 视觉编码器负责把图片“翻译”成一种数学语言&#xff08;向量&#xff09;&#xff0c;告诉大模型&#xff1a;“嘿&#xff0c;这里有一堆黑线条组成了这种形状”。然后大模型根据它的知识库反应过来&#xff1a;“哦&#xff0c;这…...

多屏时代的窗口效率引擎:Rectangle智能布局解决方案

多屏时代的窗口效率引擎&#xff1a;Rectangle智能布局解决方案 【免费下载链接】Rectangle Move and resize windows on macOS with keyboard shortcuts and snap areas 项目地址: https://gitcode.com/gh_mirrors/re/Rectangle 场景痛点&#xff1a;当混乱成为工作流的…...

整流器专题(2)【详细讲解】电网电压不平衡时PWM整流器控制:基于双电流功率平衡算法抑制二次谐波

整流器专题&#xff08;2&#xff09;【详细讲解】电网电压不平衡时PWM整流器控制&#xff1a;基于双电流功率平衡算法抑制二次谐波阅读前注意&#xff1a; 1、 此平台私信不回复&#xff0c;统一在b站回复&#xff0c;展示内容与b站一致&#xff0c;视频链接如下:https://www.…...

LAYONTHEGROUND筛

一、什么是requests&#xff1f; requests 是一个用于发送HTTP请求的 Python 库。 它可以帮助你&#xff1a; 轻松发送GET、POST、PUT、DELETE等请求 处理Cookie、会话等复杂性 自动解压缩内容 处理国际化域名和URL 二、应用场景 requests 广泛应用于以下实际场景&#xff1a; …...

如何在VS Code中高效处理JSON文件:终极编辑器插件使用指南

如何在VS Code中高效处理JSON文件&#xff1a;终极编辑器插件使用指南 【免费下载链接】vscode-json Json for Visual Studio Code 项目地址: https://gitcode.com/gh_mirrors/vs/vscode-json JSON作为现代开发中最常用的数据交换格式&#xff0c;几乎贯穿了从配置文件到…...

3步掌握终极鼠标悬停翻译神器:MouseTooltipTranslator完整使用指南

3步掌握终极鼠标悬停翻译神器&#xff1a;MouseTooltipTranslator完整使用指南 【免费下载链接】MouseTooltipTranslator Mouseover Translate Any Language At Once - Chrome Extension: PDF Translator, EBOOK, EPUB, OCR, TTS, NETFLIX, YOUTUBE DUAL SUBTITLES, GOOGLE DOC…...

Windows游戏多开检测实战:从进程枚举到信号量的5种实现与破解技巧

Windows游戏多开检测与破解&#xff1a;5种核心机制深度解析 在游戏开发和运营过程中&#xff0c;限制同一台设备上同时运行多个游戏实例是常见的需求。这种机制不仅关乎商业利益保护&#xff0c;也涉及游戏平衡性和反作弊系统的有效性。对于技术爱好者而言&#xff0c;理解这些…...

4大核心能力!March7thAssistant让崩坏:星穹铁道实现全自动游戏体验

4大核心能力&#xff01;March7thAssistant让崩坏&#xff1a;星穹铁道实现全自动游戏体验 【免费下载链接】March7thAssistant 崩坏&#xff1a;星穹铁道全自动 三月七小助手 项目地址: https://gitcode.com/gh_mirrors/ma/March7thAssistant March7thAssistant是一款专…...

终极指南:如何用PoeCharm中文版轻松规划你的《流放之路》角色构建

终极指南&#xff1a;如何用PoeCharm中文版轻松规划你的《流放之路》角色构建 【免费下载链接】PoeCharm Path of Building Chinese version 项目地址: https://gitcode.com/gh_mirrors/po/PoeCharm 还在为《流放之路》复杂的角色构建系统感到头疼吗&#xff1f;面对海量…...

我不是在用 AI 助手,我在把自己的能力沉淀成组织资产赡

1. 什么是 Apache SeaTunnel&#xff1f; Apache SeaTunnel 是一个非常易于使用、高性能、支持实时流式和离线批处理的海量数据集成平台。它的目标是解决常见的数据集成问题&#xff0c;如数据源多样性、同步场景复杂性以及资源消耗高的问题。 核心特性 丰富的数据源支持&#…...