【教程向】从零开始创建浏览器插件(三)解决 Chrome 扩展中弹出页面、背景脚本、内容脚本之间通信的问题

第三步:解决 Chrome 扩展中弹出页面、背景脚本、内容脚本之间通信的问题

Chrome 扩展开发中,弹出页面(Popup)、背景脚本(Background Script)、内容脚本(Content Script)各自拥有独立的 JavaScript 执行环境。这种设计可以增强安全性,但同时也带来了数据共享和传递上的问题。

本文将详细探讨弹出页面、背景脚本、内容脚本之间的通信方式,并提供解决方案的代码示例。

在这里插入图片描述

问题概述

弹出页面、背景脚本、内容脚本的独立运行环境带来了以下问题:

  1. 数据共享难题:它们各自拥有不同的执行环境,无法直接访问彼此的 JavaScript 变量或对象。
  2. 事件监听问题:弹出页面关闭后,其事件监听器会被卸载,无法保持持久监听状态。
  3. 权限隔离:内容脚本与弹出页面的权限各自独立,内容脚本无法直接访问弹出页面的 DOM 元素,反之亦然。

解决方案:相互通信的方式

Chrome 扩展提供了多种通信方式来解决这些问题:

1. 使用 chrome.runtime 消息传递

chrome.runtime API 提供了弹出页面、背景脚本和内容脚本之间通信的机制。

弹出页面与背景脚本的通信

背景脚本 (background.js):

// background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {if (message.type === "getData") {// 获取数据并通过 sendResponse 返回给弹出页面const data = {info: "background data"};sendResponse(data);}return true;
});

弹出页面 (popup.js):

// popup.js
document.addEventListener("DOMContentLoaded", function () {// 向背景脚本请求数据chrome.runtime.sendMessage({type: "getData"}, (response) => {console.log("Received data from background:", response);});
});
内容脚本与背景脚本的通信

背景脚本 (background.js):

// background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {if (message.type === "fetchContentData") {// 从后台处理数据并返回给内容脚本const data = {content: "Processed data from background"};sendResponse(data);}return true;
});

内容脚本 (content.js):

// content.js
chrome.runtime.sendMessage({type: "fetchContentData"}, (response) => {console.log("Received data from background:", response);
});
弹出页面与内容脚本的通信

直接通信方式不可行,但可以通过背景脚本作为中介实现通信。

弹出页面 (popup.js):

// popup.js
function sendMessageToContentScript(tabId, message) {chrome.tabs.sendMessage(tabId, message, (response) => {console.log("Response from content script:", response);});
}document.addEventListener("DOMContentLoaded", function () {chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {sendMessageToContentScript(tabs[0].id, {type: "greeting", text: "Hello from popup!"});});
});

内容脚本 (content.js):

// content.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {if (message.type === "greeting") {console.log("Received message from popup:", message.text);sendResponse({text: "Hello from content script!"});}
});

2. 使用 chrome.storage 共享数据

chrome.storage API 允许持久化并共享数据,以便在不同环境间传递。

背景脚本 (background.js):
// background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {if (message.type === "saveData") {chrome.storage.local.set({sharedData: message.data}, () => {sendResponse({status: "Data saved"});});} else if (message.type === "loadData") {chrome.storage.local.get("sharedData", (result) => {sendResponse({data: result.sharedData});});}return true;
});
弹出页面 (popup.js):
// popup.js
document.addEventListener("DOMContentLoaded", function () {// 向背景脚本请求数据chrome.runtime.sendMessage({type: "loadData"}, (response) => {console.log("Data loaded from storage:", response.data);});// 保存数据到 storagechrome.runtime.sendMessage({type: "saveData", data: "New shared data"}, (response) => {console.log(response.status);});
});
内容脚本 (content.js):
// content.js
chrome.runtime.sendMessage({type: "loadData"}, (response) => {console.log("Data loaded from storage:", response.data);
});

3. 使用 chrome.tabs API 与当前活动标签通信

chrome.tabs API 可以帮助我们确定活动标签,并使用 chrome.scripting 在该标签中注入代码。

弹出页面 (popup.js):
// popup.js
document.addEventListener("DOMContentLoaded", function () {chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {chrome.scripting.executeScript({target: {tabId: tabs[0].id},func: () => {document.body.style.backgroundColor = "pink";}});});
});

总结

由于 Chrome 扩展的不同脚本运行环境是相互独立的,所以开发者在设计扩展时需要使用不同的通信机制来确保数据共享和功能协同。本文提供了多种解决方案,开发者可以根据需求选择最合适的方式:

  1. chrome.runtime 消息传递
  2. chrome.storage 数据持久化
  3. chrome.tabs 标签控制与代码注入

希望本文能够帮助你在 Chrome 扩展开发中更好地处理弹出页面、背景脚本和内容脚本之间的通信问题!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/327298.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序知识点归纳(一)

前言:适用于有一定基础的前端开发同学,完成从网页开发到小程序开发的知识转换。 先立框架,后砌墙壁 回顾:了解微信小程序开发流程-CSDN博客 初始页面结构,三部分pages、utils、配置,分别存放页面、工具类…

OpenAI Whisper 语音转文本实验

为了实现语音方式与大语言模型的对话,需要使用语音识别(Voice2Text)和语音输出(Text2Voice)。感觉这项技术已比较成熟了,国内也有许多的机构开发这项技术,但是像寻找一个方便测试的技术居然还不…

使用Vue调用ColaAI Plus大模型,实现聊天(简陋版)

首先去百度文心注册申请自己的api 官网地址&#xff1a;LuckyCola 注册点开个人中心 查看这个文档自己申请一个ColaAI Plus定制增强大模型API | LuckyColahttps://luckycola.com.cn/public/docs/shares/api/colaAi.html来到vue的页面 写个样式 <template><Header …

C++ | Leetcode C++题解之第79题单词搜索

题目&#xff1a; 题解&#xff1a; class Solution { public:bool exist(vector<vector<char>>& board, string word) {rows board.size();cols board[0].size();for(int i 0; i < rows; i) {for(int j 0; j < cols; j) {if (dfs(board, word, i, …

dnf手游攻略,新手入坑必备!

一、角色创建策略 在DNF手游中&#xff0c;角色创建是玩家初入游戏的首要步骤。为最大化游戏体验和收益&#xff0c;新手玩家通常建议创建三个角色&#xff1a;一个主账号和两个副账号。 主账号选择 主账号的选择应基于玩家个人的喜好和对职业的熟悉程度。无论选择哪个职业&a…

Gone框架介绍17 - 创建一个可运行在生产环境的Web项目

gone是可以高效开发Web服务的Golang依赖注入框架 github地址&#xff1a;https://github.com/gone-io/gone 文档原地址&#xff1a;https://goner.fun/zh/guide/auto-gen-priest.html 请帮忙在github上点个 ⭐️吧&#xff0c;这对我很重要 &#xff1b;万分感谢&#xff01;&a…

视频汇聚管理/安防监控系统EasyCVR如何开启和调用验证码登录接口?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。视频汇聚融合管理平台EasyCVR既具备传统安防视…

C语言写扫雷游戏(数组和函数实践)

目录 最后是代码啦&#xff01; 手把手教你用C语言写一个扫雷游戏&#xff01; 1.我们搭建一下这个多文件形式的扫雷游戏文件结构 2.在主函数里面设置一个包含游戏框架的菜单 菜单可以方便游戏玩家选择要进行的动作和不断地进行下一局。 3.switch语句连接不同的结果 菜单可…

AI与边缘设备,光子芯片,AI规划能力,自然语言驱动的AI游戏

1 Archetype AI 发布了一个创新的人工智能平台 —— Newton 这是一个专门为理解物理世界设计的基础模型。 Newton 设计用于连接实时物理数据&#xff0c;其数据源是全球数十亿传感器的输入&#xff0c;实现了对物理现实的直接解读。 利用从各种传感器&#xff08;如加速度计…

被动防护不如主动出击

自网络的诞生以来&#xff0c;攻击威胁事件不断涌现&#xff0c;网络攻防对抗已然成为信息时代背景下的一场无硝烟的战争。然而&#xff0c;传统的网络防御技术&#xff0c;如防火墙和入侵检测技术&#xff0c;往往局限于一种被动的敌暗我明的防御模式&#xff0c;面对攻击者无…

Windows Qt中支持heic 图片显示

安装vcpkg&#xff1a; git clone https://github.com/microsoft/vcpkg 执行脚本&#xff1a; .\vcpkg\bootstrap-vcpkg.bat 在安装之前如果需要指定vs的编译器&#xff0c; 在如下文件中做更改&#xff0c; 我指定的是用vs2019编译的&#xff1a; D:\vcpkg\vcpkg\triplets 增…

android图标底色问题,debug与release不一致

背景 在android 8&#xff08;sdk 26&#xff09;之前的版本&#xff0c;直接使用图片文件作为图标&#xff0c;开发时比较容易控制图标&#xff0c;但是不同的安卓定制版本就不容易统一图标风格了。 在android 8及之后的版本&#xff0c;图标对应的是ic_launcher.xml&#x…

VC 编程开发中的 封装类 :log日志类 和SQL server 操作类 源代码

VC 编程开发中的 封装类 &#xff1a;日志类 和SQL server 操作类 源代码 在VC&#xff08;Visual C&#xff09;开发中&#xff0c;日志文件输出是一个至关重要的环节&#xff0c;它对于程序调试、问题排查以及系统监控等方面都具有不可替代的作用。以下是对日志文件输出在VC开…

网站localhost和127.0.0.1可以访问,本地ip不可访问解决方案

部署了一个网站, 使用localhost和127.0.0.1加端口号可以访问, 但是使用本机的ip地址加端口号却不行. 原因可能有多种. 可能的原因: 1 首先要确认是否localhost对应的端口是通的(直接网址访问), 以及你无法访问的那个本机ip是否正确(使用ping测试)&#xff1b; 2 检查本机的防火…

好题总结汇总

好题总结汇总 总结一些做完很有收获的题。 一、经典问题 DP的结合 1、题意&#xff1a; 给定 n n n 种颜色的球的数量 a 1 , a 2 , . . . , a n a_1, a_2, ..., a_n a1​,a2​,...,an​&#xff0c;选出一些不同种类的球(也就是在n种球中选球的任意情况)&#xff0c;将球…

企业如何通过云服务器实现全球连通运营

如果说互联网是一座桥&#xff0c;连接起了全球各地的信息&#xff0c;那云服务器就如同一座高速公路&#xff0c;帮助企业轻松实现跨国家、跨时区的全球运营。 这个听起来像科幻电影的情节其实已经成为了我们现实生活的一部分。现在就来具体看一下如何做到这一点吧。 其一&…

【Linux】Linux——Centos7安装

【Linux】Linux——Centos7安装 新建虚拟机 选择自定义安装下一步 硬件兼容性使用默认最高即可&#xff0c;下一步 选择稍后安装操作系统&#xff0c;下一步 选择客户机操作系统为 Linux &#xff0c;并选择下方版本为所安装 Linux 镜像同版本&#xff0c;下一步 虚拟机名称与…

idea-自我常见配置

1. 主题配置 2. 显示方法分隔符 Editor->General->Appearance 3. 忽略大小写提示 Editor->General->Code Completion 4. 自动导包 Editor->general->Auto Import 5. 取消单行显示Tabs Editor->General->Editor Tabs 效果如下图&#xff1a; 6. 设置…

idea启动Jsp非maven项目时的一些步骤

文章目录 事前准备eclipse项目举例idea打开eclipse项目安装tomcat配置启动项启动测试 一些小问题到不到servlet 事前准备 非社区版idea【否则启动项无法配置】tomcatmysql eclipse项目举例 idea打开eclipse项目 剩下的全部下一步即可 安装tomcat 自己的文章 Javaweb - t…

OpenAI GPT-4

本文翻译整理自&#xff1a;https://openai.com/index/gpt-4-research/ (March 14, 2023) 文章目录 一、关于 GPT-4二、能力视觉输入Visual inputs: chart reasoningSample 2 of 7 操纵性Steerability: Socratic tutorSample 1 of 3 三、局限性四、风险与缓解措施五、训练流程…