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

简介: 在Chrome插件开发中,遇到问题:存储包含Map和数组的复杂数据结构到`chrome.storage.local`时,读取为空。原因在于`chrome.storage.local`只支持JSON序列化,而Map无法直接序列化。解决方案是使用`serializeMap`和`deserializeMap`方法将Map转换为数组进行存储和读取。更新的`saveMindData`和`getMindData`方法实现了数据的正确序列化和反序列化。

问题描述

最近俺在接触 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;
}
目录
相关文章
|
10天前
|
存储 人工智能 C语言
数据结构基础详解(C语言): 栈的括号匹配(实战)与栈的表达式求值&&特殊矩阵的压缩存储
本文首先介绍了栈的应用之一——括号匹配,利用栈的特性实现左右括号的匹配检测。接着详细描述了南京理工大学的一道编程题,要求判断输入字符串中的括号是否正确匹配,并给出了完整的代码示例。此外,还探讨了栈在表达式求值中的应用,包括中缀、后缀和前缀表达式的转换与计算方法。最后,文章介绍了矩阵的压缩存储技术,涵盖对称矩阵、三角矩阵及稀疏矩阵的不同压缩存储策略,提高存储效率。
|
12天前
|
存储 算法 C语言
数据结构基础详解(C语言): 二叉树的遍历_线索二叉树_树的存储结构_树与森林详解
本文从二叉树遍历入手,详细介绍了先序、中序和后序遍历方法,并探讨了如何构建二叉树及线索二叉树的概念。接着,文章讲解了树和森林的存储结构,特别是如何将树与森林转换为二叉树形式,以便利用二叉树的遍历方法。最后,讨论了树和森林的遍历算法,包括先根、后根和层次遍历。通过这些内容,读者可以全面了解二叉树及其相关概念。
|
12天前
|
存储 机器学习/深度学习 C语言
数据结构基础详解(C语言): 树与二叉树的基本类型与存储结构详解
本文介绍了树和二叉树的基本概念及性质。树是由节点组成的层次结构,其中节点的度为其分支数量,树的度为树中最大节点度数。二叉树是一种特殊的树,其节点最多有两个子节点,具有多种性质,如叶子节点数与度为2的节点数之间的关系。此外,还介绍了二叉树的不同形态,包括满二叉树、完全二叉树、二叉排序树和平衡二叉树,并探讨了二叉树的顺序存储和链式存储结构。
|
12天前
|
存储 算法 C语言
C语言手撕数据结构代码_顺序表_静态存储_动态存储
本文介绍了基于静态和动态存储的顺序表操作实现,涵盖创建、删除、插入、合并、求交集与差集、逆置及循环移动等常见操作。通过详细的C语言代码示例,展示了如何高效地处理顺序表数据结构的各种问题。
|
22天前
|
Web App开发 存储 前端开发
《Chrome谷歌插件Top10》开发最好用的谷歌插件
本文介绍了多个实用的浏览器插件及其安装方法。包括CSDN浏览器助手,提供高效开发工具;FeHelper,前端必备工具,支持格式化、压缩等功能;uBlock Origin,有效屏蔽广告和弹窗;PageLiner,网页标尺工具,便于前端设计;Fatkun,批量下载图片;Smallpdf,文件转换工具;Octotree,GitHub代码树插件;Awesome Screenshot,截图与录屏工具;ColorZilla,颜色拾取器;Dark Reader,暗黑模式阅读插件。安装方式有通过Chrome商店搜索或下载crx插件本地安装。
40 11
|
24天前
|
Web App开发 JSON 前端开发
30个Chrome 灵魂插件!
30个Chrome 灵魂插件!
|
1月前
|
Web App开发 JSON 安全
【跨域难题终结者】:一键解锁Chrome浏览器神秘设置,彻底告别开发阶段的跨域烦恼!
【8月更文挑战第20天】跨域是前端开发常遇难题,尤其在前后端分离项目中。浏览器因安全考量会阻止不同源间的请求。本文对比CORS、JSONP、代理服务器等解法,并介绍开发阶段通过调整Chrome设置来临时禁用跨域限制的方法,提供启动Chrome及使用`fetch`API示例,适合快速测试。但请注意这不适用于生产环境,存在一定安全风险。
113 1
|
1月前
|
Web App开发 前端开发 JavaScript
手摸手教你,从0到1开发一个Chrome浏览器插件
开发 Chrome 插件既有趣又具成就感。本教程将引导你从零开始,逐步创建一个简单的 Chrome 插件。首先了解 Chrome 插件是可增强浏览器功能的小程序。以一个基础示例开始,你将学习如何设置开发环境,包括安装 Chrome 和准备文本编辑器,并掌握 HTML、CSS 和 JavaScript 的基础知识。接着,我们将构建插件的基本结构,涉及 `manifest.json` 配置文件、`background.js` 后台脚本、`popup.html` 用户界面以及 `style.css` 样式表。
144 8
|
1月前
|
Web App开发
Chrome 护眼模式 - 黑暗模式 - 夜眼(Night Eye) 插件
Chrome 护眼模式 - 黑暗模式 - 夜眼(Night Eye) 插件
31 0
Chrome 护眼模式 - 黑暗模式 - 夜眼(Night Eye) 插件
|
1月前
|
存储 Java
数据结构中的哈希表(java实现)利用哈希表实现学生信息的存储
这篇文章通过Java代码示例展示了如何实现哈希表,包括定义结点类、链表类、数组存储多条链表,并使用简单的散列函数处理冲突,以及如何利用哈希表存储和查询学生信息。
数据结构中的哈希表(java实现)利用哈希表实现学生信息的存储