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

【Chrome插件】如何在Chrome插件开发中处理复杂数据结构的存储

最近俺在接触 Chrome 插件开发,需要把一个数据存放到浏览器的存储中。这个数据结构有点复杂,它包含一个 Map 和一个数组。我使用 chrome.storage.local API来存储这个数据,然后在另一个地方获取数据。保存数据的代码并没有报错,但是俺发现获取的时候获取结果的内容为空,这是为什么呢?

下面是我封装的保存数据和获取数据的方法:

// 要存储的数据结构
const mindDataObj = {keywordMap: new Map(),mindDataArr: []
};/*** 获取存储对象* @param {string} key 存储对象的键* @returns {Promise<Object>} 返回一个包含存储对象的 Promise*/
export async function getObject(key) {return new Promise((resolve, reject) => {chrome.storage.local.get([key], (result) => {if (chrome.runtime.lastError) {return reject(chrome.runtime.lastError)}resolve(result[key] || {})})})
}/*** 保存存储对象* @param {string} key 存储对象的键* @param {Object} obj 要保存的对象* @returns {Promise<void>} 返回一个 Promise,表示操作完成*/
export async function saveObject(key, obj) {return new Promise((resolve, reject) => {chrome.storage.local.set({ [key]: obj }, () => {if (chrome.runtime.lastError) {return reject(chrome.runtime.lastError)}resolve()})})
}

为什么会这样?

经过查找资料发现,chrome.storage.local 的存储机制只能存储和检索序列化的 JSON 对象,虽然JSON可以很好地处理对象和数组,但对于MapSet等ES6中引入的复杂数据结构,JSON是无法直接序列化和反序列化的。因此,尽管你可能没有在保存数据时遇到错误,但在尝试读取非JSON兼容类型的数据时,这些数据将因无法被正确序列化而丢失。

解决方案

总之一句话:chrome.storage.local 只能存储 JSON 兼容的数据类型(如对象、数组、字符串、数字等),MapSet 需要转换为对象或数组才能正确存储。在这里,我们通过 chrome.storage.local 存储时需要先进行序列化处理,而在读取时需要进行反序列化处理。

步骤1: 序列化和反序列化Map对象

我们先增加两个方法做序列化的处理,serializeMapdeserializeMap 方法用于将 Map 对象转换为数组,从而可以存储在 chrome.storage.local 中,并在读取时将其转换回 Map 对象。

/*** 序列化Map对象* @param {Map} map 要序列化的Map对象* @returns {Object} 序列化后的对象*/
function serializeMap(map) {return Array.from(map.entries());
}/*** 反序列化Map对象* @param {Array} entries 序列化后的对象* @returns {Map} 反序列化后的Map对象*/
function deserializeMap(entries) {return new Map(entries);
}

步骤2: 存储和读取数据

然后再增加操作数据的方法,saveMindDatagetMindData 方法用于保存和获取 mindDataObj 格式的数据,包括序列化和反序列化步骤。

/*** 保存mindDataObj格式的数据* @param {string} key 存储对象的键* @param {Object} initMindDataObj 要保存的对象* @returns {Promise<void>} 返回一个 Promise,表示操作完成*/
export async function saveMindData(key, mindDataObj) {const serializedData = {keywordMap: serializeMap(mindDataObj.keywordMap),mindDataArr: mindDataObj.mindDataArr};await saveObject(key, serializedData);
}/*** 获取mindDataObj格式的数据* @param {string} key 存储对象的键* @returns {Promise<Object>} 返回一个包含mindDataObj格式数据的 Promise*/
export async function getMindData(key) {const serializedData = await getObject(key);const mindDataObj = {keywordMap: deserializeMap(serializedData.keywordMap || []),mindDataArr: serializedData.mindDataArr || []};return mindDataObj;
}

相关文章:

【Chrome插件】如何在Chrome插件开发中处理复杂数据结构的存储

最近俺在接触 Chrome 插件开发&#xff0c;需要把一个数据存放到浏览器的存储中。这个数据结构有点复杂&#xff0c;它包含一个 Map 和一个数组。我使用 chrome.storage.local API来存储这个数据&#xff0c;然后在另一个地方获取数据。保存数据的代码并没有报错&#xff0c;但…...

MySQL 保姆级教程(二):使用 MySQL 检索数据

使用 MySQL 3.2 选择数据库 使用数据库: 输入: USE 数据库名;输出: Database changed分析: 不返回任何结果&#xff0c;显示某种形式的通知 ​ 例如: 使用 crashcourse 数据库 use crashcourse; 3.3 了解数据库和表 列出所有的数据库: 输入: SHOW DATABASES;输出: --------…...

Sui Bridge在测试网上线并推出10万SUI激励计划

是一种为Sui设计的原生桥接协议&#xff0c;专门用于在Sui与其他网络之间桥接资产和数据。今天&#xff0c;Sui Bridge宣布在测试网上线。作为一种原生协议&#xff0c;Sui Bridge能够在Ethereum和Sui之间轻松且安全地转移ETH、wBTC、USDC和USDT&#xff0c;使其成为Sui基础设施…...

Spring系统学习 - Bean的作用域

bean作用域介绍 Spring框架提供了不同的作用域来管理Bean的生命周期和可见性&#xff0c;这对于控制不同类型的组件和处理并发请求尤其重要。 singleton&#xff08;默认&#xff09;&#xff1a; 每个Spring IoC容器只有一个bean实例。当容器创建bean后&#xff0c;它会被缓存…...

贪吃蛇双人模式设计(2)

敲上瘾-CSDN博客控制台程序设置_c语言控制程序窗口大小-CSDN博客贪吃蛇小游戏_贪吃蛇小游戏csdn-CSDN博客 一、功能实现&#xff1a; 玩家1使用↓ → ← ↑按键来操作蛇的方向&#xff0c;使用右Shift键加速&#xff0c;右Ctrl键减速玩家2使用W A S D按键来操作蛇的方向&am…...

mysql什么时候不需要建立索引

WHERE 条件&#xff0c;GROUP BY&#xff0c;ORDER BY 里用不到的字段&#xff0c;索引的价值是快速定位&#xff0c;如果起不到定位的字段通常是不需要创建索引的&#xff0c;因为索引是会占用物理空间的。字段中存在大量重复数据&#xff0c;不需要创建索引&#xff0c;比如性…...

热门开源项目推荐:技术与地址概览

随着开源项目的不断兴起&#xff0c;越来越多的优秀项目涌现出来&#xff0c;为开发者们提供了丰富的资源和灵感。在此&#xff0c;我将为大家推荐几个热门的开源项目&#xff0c;并附上它们的开源地址&#xff0c;以供大家参考和了解。 1. TensorFlow 项目简介&#xff1a; …...

Golang的channel

目录 基本使用 channel 数据结构 阻塞的协程队列 协程节点 构建 channel 写流程 读流程 非阻塞与阻塞 closechan(关闭) 基本使用 创建无缓存 channel c : make(chan int) //创建无缓冲的通道 cc : make(chan int,0) //创建无缓冲的通道 c 创建有缓存 channel c : m…...

DIYGW可视化开发工具:微信小程序与多端应用开发的利器

一、引言 随着移动互联网的飞速发展&#xff0c;微信小程序以其轻便、易用和跨平台的特点受到了广泛关注。然而&#xff0c;微信小程序的开发相较于传统的H5网页开发&#xff0c;在UI搭建和交互设计上存在一定的挑战。为了应对这些挑战&#xff0c;开发者们一直在寻找更加高效…...

docker——基础知识

简介 一、什么是虚拟化和容器化 ​ 实体计算机叫做物理机&#xff0c;有时也称为寄主机&#xff1b; ​ 虚拟化&#xff1a;将一台计算机虚拟化为多台逻辑计算机&#xff1b; ​ 容器化&#xff1a;一种虚拟化技术&#xff0c;操作系统的虚拟化&#xff1b;将用户空间软件实…...

SAP MMRV/MMPV 物料账期月结月底月初开关

公告&#xff1a;周一至周五每日一更&#xff0c;周六日存稿&#xff0c;请您点“关注”和“在看”&#xff0c;后续推送的时候不至于看不到每日更新内容&#xff0c;感谢。 这是一条刮刮乐&#xff0c;按住全部选中&#xff1a;点关注的人最帅最美&#xff0c;欢迎&#xff1…...

五分钟看懂如何解决FP独立站的广告投放问题

在数字化时代的浪潮中&#xff0c;跨境电商的独立站成为了商家们的新宠。与传统的电商平台相比&#xff0c;独立站在品牌建设、市场定位以及客户体验上提供了更多的自由度和创新空间。然而&#xff0c;这些独立站尤其是销售FP产品的站点&#xff0c;在广告投放上遇到了重重障碍…...

学习分享-FutureTask

前言 今天再改简历的时候回顾了之前实习用到的FutureTask&#xff0c;借此来回顾一下相关知识。 FutureTask 介绍 FutureTask 是 Java 并发包&#xff08;java.util.concurrent&#xff09;中的一个类&#xff0c;用于封装异步任务。它实现了 RunnableFuture 接口&#xff0…...

Javaweb02-XML概述

第一章 XML概述 1.XML基本概念 什么是xml&#xff1f; **a.**引入的原因&#xff1a;为了解决不同不同语言之间的数据传输的格式不同 **b.**概念&#xff1a;XML是一种可扩展标记语言&#xff0c;适用于不同数据之间的数据交换 **c.**XML文档&#xff1a;通过元素的嵌套&a…...

Linux shell编程基础

Shell 是一个用 C 语言编写的程序&#xff0c;它是用户使用 Linux 的桥梁。Shell 既是一种命令语言&#xff0c;又是一种程序设计语言。Shell 是指一种应用程序&#xff0c;这个应用程序提供了一个界面&#xff0c;用户通过这个界面访问 Linux 内核的服务。 Shell 脚本&#x…...

2024.6.12 作业 xyt

今日课堂练习&#xff1a;vector构造函数 #include <iostream> #include <vector> using namespace std;void printVector(vector<int> &v) {vector<int>::iterator iter;for(iterv.begin(); iter ! v.end(); iter){cout << *iter <<…...

QTTabBar在重置Internet Explorer后失效

网上常见的办法是&#xff1a; 打开IE浏览器>>设置>>Internet选项>>高级。勾选启用第三方浏览器扩展&#xff0c;重启后生效。 打开IE浏览器-设置–管理加载项&#xff0c;启用QTTabBar。 实际在Win10上使用的时候会遇到点开IE自动跳转到Edge的问题。这时…...

Django之云存储(一)

一、介绍 用户上传的文件以及项目中使用的静态文件,除了保存在本地服务器,还在可以保存在云服务中,比如: 阿里云七牛云(课程选用)亚马逊云等1.1、使用方式 注册账号 七牛云开发者平台 实名认证 创建空间...

推挽与开漏输出

一般来说&#xff0c;微控制器的引脚都会有一个驱动电路&#xff0c;可以配置不同类型的数字和模拟电路接口。输出模式一般会有推挽与开漏输出。 推挽输出 推挽输出&#xff08;Push-Pull Output&#xff09;&#xff0c;故名思意能输出两种电平&#xff0c;一种是推&#xf…...

Sora和快手可灵背后的核心技术 | 3DVAE:通过小批量特征交换实现身体和面部的三维形状变分自动编码器

【摘要】学习3D脸部和身体生成模型中一个解开的、可解释的和结构化的潜在表示仍然是一个开放的问题。当需要控制身份特征时,这个问题尤其突出。在本文中,论文提出了一种直观而有效的自监督方法来训练一个3D形状变分自动编码器(VAE),以鼓励身份特征的解开潜在表示。通过交换不同…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...