简化Web扩展中的消息传递:WebExt-Bridge的使用指南

news2024/11/6 13:53:33

简化Web扩展中的消息传递:WebExt-Bridge的使用指南

文章目录

  • 简化Web扩展中的消息传递:WebExt-Bridge的使用指南
  • 一、简介
  • 二、安装
  • 三、快速示例
    • 1、弹出窗口
    • 2、后台服务工作者
  • 四、优势
  • 五、深入学习
  • 六、概念与上下文
    • 1、通信上下文
    • 2、主要API
      • sendMessage()
      • onMessage()
      • `allowWindowMessaging()` 和 `setNamespace()`
      • `openStream()` 和 `onOpenStreamChannel()`
      • 3、类型安全
  • 七、类型安全协议
  • 八、示例
    • 1、弹出窗口 -> 后台脚本
    • 2、内容脚本 -> 后台脚本
  • 九、安全性
  • 十、故障排除
    • 1、消息传递不起作用?
    • 2、无法发送消息给目标?
  • 十一、总结

在开发Web扩展时,各个组件之间的通信是必不可少的,但这项任务往往充满挑战。不同的浏览器对消息传递的处理略有不同,导致我们在确定消息发送目标时可能会遇到复杂的情况。为了解决这个问题,WebExt-Bridge提供了一个简单而一致的API,可以在Web扩展的不同部分之间(如background、content-script、devtools、popup、options和window上下文)发送消息。

一、简介

WebExt-Bridge 的设计初衷是简化 Web 扩展中各部分之间的通信。无论是在后台脚本、内容脚本、开发者工具、弹出窗口、选项页还是窗口上下文之间,WebExt-Bridge 都能提供一个高效且一致的方式来发送和接收消息。该包已在生产环境中经过广泛测试,例如在 Bugflow 项目中得到了应用。

WebExt-Bridge 项目最初由 Neek Sandhu(@zikaari)于 2017 年启动,现已由 Server Side Up 接手维护。我们感谢 Neek Sandhu 的贡献,并期待在未来继续推动这一项目的发展。

官网:https://serversideup.net/open-source/webext-bridge/

GitHub仓库:https://github.com/serversideup/webext-bridge

二、安装

你可以通过NPM或Yarn轻松安装WebExt-Bridge:

# 使用NPM
npm i webext-bridge

# 使用Yarn
yarn add webext-bridge

安装完成后,你就可以在扩展的不同组件之间简单地传递消息了。

三、快速示例

接下来,让我们看一个从弹出窗口向后台脚本发送消息的快速示例:

1、弹出窗口

在你的弹出窗口中,添加以下代码:

import { sendMessage } from "webext-bridge/popup";

const response = await sendMessage("ACTION", { data: data }, "background");

2、后台服务工作者

在后台服务工作者脚本中添加以下代码:

import { onMessage } from "webext-bridge/background";

onMessage("ACTION", runAction);

async function runAction({ data }) {
    // 处理数据
    // 返回数据
    return {};
}

就是这样!你已准备好在扩展的不同部分之间发送消息了。

四、优势

使用WebExt-Bridge的最大优势在于它简化了消息传递的过程。与传统的chrome.runtime.sendMessagechrome.runtime.connect方法相比,WebExt-Bridge使得代码更加简洁易读,并允许你更具体地指定消息的发送和处理位置。它还支持跨平台的解决方案,代码可以在Firefox、Chrome、Safari和Edge上运行。

五、深入学习

对于想要深入学习WebExt-Bridge的开发者,我们推荐阅读我们的书籍《构建多平台浏览器扩展》。这本书涵盖了从基础到高级主题,如消息传递、存储和调试,并特别介绍了如何使用WebExt-Bridge来简化扩展中的消息传递。

六、概念与上下文

浏览器扩展由多个上下文组成,每个上下文可以发送和接收消息。WebExt-Bridge支持的上下文包括content-script、popup、options、background和devtools。通过在代码中导入相应的模块,你可以轻松地在这些上下文中进行通信。

1、通信上下文

WebExt-Bridge支持以下几种通信上下文:

  • content-script - 注入到页面的脚本
  • popup - 扩展的弹出窗口
  • options - 选项页面
  • background - 后台脚本
  • devtools - 开发者工具

2、主要API

sendMessage()

方法签名:

sendMessage(messageId: string, data: any, destination: string)

用于向扩展的其他部分发送消息。如果目标端没有监听器,将抛出错误。监听器可以通过 Promise 获取响应。

参数说明:

  • messageId(必填,string):消息的唯一标识符。
  • data(必填,any):需要传递的数据。
  • destination(必填,string):消息的目标地址,如 backgroundpopupcontent-script@<tabId> 等。

onMessage()

方法签名:

onMessage(messageId: string, callback: function)

用于在每个上下文中注册消息监听器,当接收到指定 messageId 的消息时调用回调函数。

参数说明:

  • messageId(必填,string):需要监听的消息标识符。
  • callback(必填,function):处理消息的回调函数,可以返回值或 Promise 作为响应。

allowWindowMessaging()setNamespace()

注意:这是危险操作,仅在必要时使用。

  • allowWindowMessaging(namespace: string):仅在内容脚本中调用,用于解锁特定页面的消息传递通道。
  • setNamespace(namespace: string):在加载的远程页面顶层框架中调用,用于设置消息传递的命名空间,确保消息属于特定的扩展。

openStream()onOpenStreamChannel()

用于在调用者和目标之间打开一个流通道,适用于需要持续通信的场景。

3、类型安全

可以通过定义 Protocol 来实现类型安全:

declare module "webext-bridge" {
  export interface ProtocolMap {
    foo: { title: string }
    bar: ProtocolWithReturn<CustomDataType, CustomReturnType>
  }
}

七、类型安全协议

为了保持协议的类型一致性,WebExt-Bridge提供了类型安全的解决方案。你可以创建一个shim.d.ts文件来定义消息协议的类型,从而在不同上下文中使用时保持一致性。

shim.d.ts文件示例:

import type { ProtocolWithReturn } from 'webext-bridge'

declare module 'webext-bridge' {
  export interface ProtocolMap {
    // define message protocol types
    // see https://github.com/antfu/webext-bridge#type-safe-protocols
    'tab-prev': { title: string | undefined }
    'get-current-tab': ProtocolWithReturn<{ tabId: number }, { title?: string }>
  }
}

八、示例

以下是一些常见的使用示例:

1、弹出窗口 -> 后台脚本

从弹出窗口向后台脚本发送消息

// 弹出窗口脚本
import { sendMessage } from "webext-bridge/popup";

const sendToBackground = async () => {
    await sendMessage("RECORD_NAME", {
        first_name: 'John',
        last_name: 'Doe'
    }, "background");
}

// 后台脚本
import { onMessage } from "webext-bridge/background";

onMessage("RECORD_NAME", recordName);

async function recordName({ data }) {
    // 处理数据
    return {
        // 返回响应
    };
}

2、内容脚本 -> 后台脚本

从内容脚本向后台脚本发送消息

// 内容脚本
import { sendMessage } from "webext-bridge/content-script";

const sendToBackground = async () => {
    const response = await sendMessage('RECORD_NAME', { first_name: 'John', last_name: 'Doe' }, 'background');
    // 处理响应
}

// 后台脚本
import { onMessage } from "webext-bridge/background";

onMessage("RECORD_NAME", recordName);

async function recordName({ data }) {
    // 处理数据
    return {};
}

九、安全性

在处理 window 上下文的消息传递时,需要特别注意安全性。与 chrome.runtime.sendMessagechrome.runtime.connect 不同,WebExt-Bridge 设计上没有限制与扩展通信的站点,这意味着任何网页只要使用相同的协议和命名空间,都可以发送消息。因此,为了确保安全:

  1. 验证消息来源:在回应之前,始终验证发送者的身份。例如,使用 isInternalEndpoint 函数来验证消息是否来自可信的内部端点。
  2. 使用命名空间:通过 allowWindowMessagingsetNamespace 方法,确保只有特定的页面可以与扩展通信,避免恶意网站的干扰。

WebExt-Bridge内置了一些安全机制:

  • 默认只允许扩展内部组件通信
  • 与window上下文通信需要显式允许
  • 提供验证sender的方法

示例

import { onMessage, isInternalEndpoint } from "webext-bridge/background";

onMessage("getUserBrowsingHistory", (message) => {
    const { data, sender } = message;

    // 仅响应来自内部端点的请求
    if (isInternalEndpoint(sender)) {
        const { range } = data;
        return getHistory(range);
    }
});

十、故障排除

如果消息传递不起作用,确保WebExt-Bridge在扩展的背景页面中正确加载,并检查你的背景脚本配置是否正确。

1、消息传递不起作用?

确保 WebExt-Bridge 已在扩展的后台脚本中正确加载。即使你不需要自己的后台页面,也需要添加一个简单的后台脚本来作为消息的中继:

background.js:

import "webext-bridge/background";

manifest.json:

{
    "background": {
        "scripts": ["path/to/transpiled/background.js"]
    }
}

2、无法发送消息给目标?

在向内容脚本发送消息时,必须附加 tabId 以指定脚本所在的标签页。同时,确保在特定标签页的内容脚本中调用 allowWindowMessaging 方法,以允许与 window 上下文的消息传递。

十一、总结

WebExt-Bridge极大地简化了浏览器扩展中的消息传递,是开发扩展必备的工具之一。它提供了:

  • 简单统一的API
  • 类型安全
  • 内置安全机制
  • 跨浏览器兼容

如果你正在开发浏览器扩展,WebExt-Bridge绝对值得一试。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML 标签属性——<a>、<img>、<form>、<input>、<table> 标签属性详解

文章目录 1. `<a>`元素属性hreftargetname2. `<img>`元素属性srcaltwidth 和 height3. `<form>`元素属性actionmethodenctype4. `<input>`元素属性typevaluenamereadonly5. `<table>`元素属性cellpaddingcellspacing小结HTML元素除了可以使用全局…

仿真APP助力汽车零部件厂商打造核心竞争力

汽车零部件是汽车工业的基石&#xff0c;是构成车辆的基础元素。一辆汽车通常由上万件零部件组成&#xff0c;包括发动机系统、传动系统、制动系统、电子控制系统等&#xff0c;它们共同确保了汽车的安全、可靠性及高效运行。 在汽车产业快速发展的今天&#xff0c;汽车零部件…

.NET周刊【11月第1期 2024-11-03】

国内文章 .NET 9 AOT的突破 - 支持老旧Win7与XP环境 https://www.cnblogs.com/lsq6/p/18519287 .NET 9 引入了 AOT 支持&#xff0c;使得应用程序能够在编译时优化&#xff0c;以在老旧 Windows 系统上运行。这项技术通过静态编译&#xff0c;消除运行时的 JIT 编译&#xf…

江协科技STM32学习- P36 SPI通信外设

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

Type-C接口 PD 受电端(sink)快充协议芯片,XSP08Q应用小家电领域的方案

前言 在智能家居浪潮的推动下&#xff0c;小家电作为日常生活中不可或缺的一部分&#xff0c;其供电方式的创新与优化正逐步成为行业关注的焦点。随着快充技术的普及&#xff0c;特别是Power Delivery&#xff08;PD&#xff09;协议的广泛应用&#xff0c;一种新型供电模式—…

Memento 备忘录模式

备忘录模式 意图结构适用性实例Java Web开发中的简单示例Originator 类Memento 类Caretaker 类 文本编辑器示例1. Originator (发起人) - TextEditor2. Memento (备忘录) - TextMemento3. Caretaker (负责人) - History4. 使用示例输出 备忘录模式&#xff08;Memento Pattern&…

网络应用技术 实验二:交换机VLAN 应用(华为ensp)

目录 一、实验简介 二、实验目的 三、实验需求 四、实验拓扑 五、实验任务及要求 1、任务 1&#xff1a;在交换机上创建VLAN 并测试通信 2、任务 2&#xff1a;路由交换机实现VLAN 之间通信 六、实验步骤 1、完成任务 1 2、完成任务 2 一、实验简介 在交换机上配置 VLAN&#x…

大模型应用:新时代的多模态交互

引言 如果把大模型接入到终端设备&#xff0c;会怎么样&#xff1f; &#xff08;1&#xff09;智能交互回顾 历史文章《[智能交互复兴&#xff1a;ChatGPT 终端&#xff08;奔驰/Siri&#xff09; &#xff1f;]》中提到&#xff1a;大模型遍布多个应用场景 其中有智能对话…

一周内从0到1开发一款 AR眼镜 相机应用?

目录 1. &#x1f4c2; 前言 2. &#x1f4a0; 任务拆分 2.1 产品需求拆分 2.2 开发工作拆分 3. &#x1f531; 开发实现 3.1 代码目录截图 3.2 app 模块 3.3 middleware 模块 3.4 portal 模块 4. ⚛️ 拍照与录像 4.1 前滑后滑统一处理 4.2 初始化 View 以及 Came…

信息安全工程师(76)网络安全应急响应技术原理与应用

前言 网络安全应急响应&#xff08;Network Security Incident Response&#xff09;是针对潜在或已发生的网络安全事件而采取的网络安全措施&#xff0c;旨在降低网络安全事件所造成的损失并迅速恢复受影响的系统和服务。 一、网络安全应急响应概述 定义&#xff1a;网络安全应…

用图说明 CPU、MCU、MPU、SoC 的区别

CPU CPU 负责执行构成计算机程序的指令&#xff0c;执行这些指令所指定的算术、逻辑、控制和输入/输出&#xff08;I/O&#xff09;操作。 MCU (microcontroller unit) 不同的 MCU 架构如下&#xff0c;注意这里的 MPU 表示 memory protection unit MPU (microprocessor un…

vue3动态监听div高度案例

案例场景 场景描述&#xff1a;现在左边的线条长度需要根据右边盒子的高度进行动态变化 实践代码案例 HTML部分 <div v-for"(device, index) in devices" :key"index"><!-- 动态设置 .left-bar 的高度 --><div class"left-bar"…

【Docker系列】指定系统平台拉取 openjdk:8 镜像

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【含文档+源码】基于SpringBoot+Vue的新型吃住玩一体化旅游管理系统的设计与实现

开题报告 本文旨在探讨新型吃住玩一体化旅游管理系统的设计与实现。该系统融合了用户注册与登录、旅游景点管理、旅游攻略发帖、特色旅游路线推荐、附近美食推荐以及酒店客房推荐与预定等多项功能&#xff0c;旨在为游客提供全方位、一体化的旅游服务体验。在系统设计中&#…

B3735 [信息与未来 2018] 圣诞树

题目描述 圣诞树共有 nn 层&#xff0c;从上向下数第 11 层有 11 个星星、第 22 层有 22 个星星、以此类推&#xff0c;排列成下图所示的形状。 星星和星星之间用绳子连接。第 1,2,\cdots, n - 11,2,⋯,n−1 层的每个星星都向下一层最近的两个星星连一段绳子&#xff0c;最后一…

解决 Hypack 安装不能正常运行的引导及微软 VC++ 运行库 VCRedist

解决 Hypack 安装不能正常运行的引导及微软 VC 运行库 VCRedist 前言1、常见 Hypack 安装不能正常运行的错误1.1、无法打开大地测量参数1.2、无法运行硬件设置和组合 2、从 Hypack 2013 开始&#xff0c;程序安装后&#xff0c;在程序目标目录&#xff0c;有支持目录 Support &…

给大模型研究生一些救命建议

这篇写给大模型方向的研一新生&#xff0c;我呆证看完以后能救你们大命 首先我知道大模型算法工程师这个 title 十分诱人&#xff0c;你们现在也被导师说得一腔热血。 但是&#xff0c;大模型它跟七八年前的 CV、NLP 都不太一样&#xff0c;最不一样的点在哪里呢? 就是LLM …

Oracle基础查询

第一章 数据查询 1.1 单表查询 1.1.1 数据准备 找到分享的sql文件&#xff0c;选中文件&#xff0c;右键进行复制&#xff0c;选中以wateruser用户登录的连接&#xff0c;右键粘贴&#xff0c;然后ok确认&#xff0c;就可以将两个sql文件添加到了Datagrip的工程中&#xff0c;打…

解决com.mysql.jdbc.NonRegisteringDriver内存泄漏问题

1. 问题背景 线上出现内存报警&#xff0c;通过dump文件&#xff0c;MAT分析&#xff0c;发现mysql-connector-java 有内存泄漏问题 2.问题分析 然后看大对象列表&#xff0c;NonRegisteringDriver 对象确实占内存比较多&#xff0c;里面村的数据库连接的虚引用占比较多 3.解…

如何优雅处理异常?处理异常的原则

前言 在我们日常工作中&#xff0c;经常会遇到一些异常&#xff0c;比如&#xff1a;NullPointerException、NumberFormatException、ClassCastException等等。 那么问题来了&#xff0c;我们该如何处理异常&#xff0c;让代码变得更优雅呢&#xff1f; 1 不要忽略异常 不知…