我正在参加「掘金·启航计划」
本节将深入介绍 Google Chrome 插件的进阶特性之一:Message Passing API。通过详细讲解 Message Passing API 的概念、作用和运行方式,您将能够理解插件间的消息传递机制,并学会如何在插件中实现跨页面通信和数据交换。通过深入学习 Message Passing API,您可以为插件开发增加更多的功能和交互性,提升用户体验。
课程目录(暂定18节)
后续可持续关注此贴,目录路径都会补上,点击即可跳转前往
- 序章:拓展技术池,一起来探索谷歌插件吧!
- 插件结构:manifest.json 配置文件详解
- 实战开发:创建自己的第一个Google插件
- 插件结构:background.js 文件详解
- 进阶高级:Browser Action API 详解
- 进阶高级:Tabs Manager API 详解
- 谷歌插件开发:content.js 文件详解
- 谷歌插件开发:Content Script API 详解
- 谷歌插件开发:Message Passing API 详解
- 谷歌插件开发:Storage API 详解
- 谷歌插件开发:File System Access API 详解
- 谷歌插件开发:XMLHttpRequest 详解
- 进阶高级:Bookmarks API 详解
- 进阶高级:Downloads API 详解
- 进阶高级:如何使用vue来开发一款Google插件
- 实战开发:从零开发一款企业级Google插件(上)
- 实战开发:从零开发一款企业级Google插件(下)
- 收官之作:总结与展望
一. 基本介绍
在开发 Google Chrome 插件时,经常会遇到需要不同插件页面之间进行通信和数据传递的情况。为了实现这种跨页面的交互,Chrome 提供了 Message Passing API。Message Passing API 允许插件的不同部分之间安全地发送消息和共享数据,实现了插件的高度灵活性和可扩展性。
Message Passing API 是 Chrome 插件提供的一种机制,可以让不同的插件组件之间进行通信。通过该 API,插件的不同组件(如 background page、content script、popup 窗口等)可以互相发送消息和接收消息,以实现数据传递和功能调用等操作。
在 Message Passing API 中,消息的发送和接收是基于异步的事件驱动模型,即发送方通过 API 发送消息,接收方通过注册事件监听器来接收消息。当消息被发送时,接收方会触发监听器并执行相应的操作。
作用
它的基本原理是通过发送和接收消息来实现通信。插件中的不同部分可以使用 API 提供的方法发送消息,并在接收方注册监听器以接收消息。消息可以是简单的文本、JSON 对象或包含更复杂数据结构的信息。
在实际开发场景中,我们可以使用 Message Passing API 来实现以下功能,例如:
- 插件的不同组件之间的通信: 它可以让插件的不同组件之间进行通信,包括 background page、content script、popup 窗口等。
- 插件和网页之间的通信: 通过 Message Passing API,插件可以和网页之间进行通信,实现数据传递和功能调用等操作。
- 插件和服务器之间的通信: 通过 Message Passing API,插件可以和服务器之间进行通信,实现数据传递和功能调用等操作。
- 插件和其他插件之间的通信: 通过 Message Passing API,插件可以和其他插件之间进行通信,实现数据传递和功能调用等操作。
Message Passing API 的作用在于帮助Chrome插件不同组件之间进行协作,以实现更强大的功能。例如,后台页面可以监听用户操作,同时控制着弹出窗口的显示和隐藏;弹出窗口可以向后台页面发送请求,获取数据并更新UI;内容脚本可以与当前打开的网页交互,获取或修改页面上的元素等。
运行方式
Message Passing API 的运行方式涉及两个主要的角色:发送方和接收方。下面将介绍它们的运行方式和交互流程。
- 发送消息:
-
- 在发送方页面中,使用 chrome.runtime.sendMessage() 方法发送消息。该方法接受三个参数:目标插件的标识符、要发送的消息和一个可选的回调函数。
- 消息可以是简单的文本或包含更复杂数据结构的 JSON 对象。
- 接收消息:
-
- 在接收方页面中,通过注册消息监听器来接收消息。使用 chrome.runtime.onMessage 方法注册监听器,并定义一个回调函数来处理接收到的消息。
- 监听器可以注册在后台页面、内容脚本和其他插件页面。
- 跨页面通信:
-
- 插件页面之间的消息传递可以通过指定目标插件的标识符来实现。可以使用 chrome.runtime.connect() 方法建立插件页面之间的长连接,并通过连接对象发送和接收消息。
- 错误处理和回调:
-
- 当发送消息时,可以提供一个可选的回调函数来处理发送操作的结果。
- 在接收消息时,可以选择返回一个结果给发送方,通过回调函数获取接收操作的结果。
需要注意的事项 ⚠️
- API 的参数和返回值必须是可序列化的数据类型,如字符串、数字、布尔值等。
- 消息传递过程中,需要对数据进行编码和解码,以保证数据的完整性和正确性。
- 由于消息传递是异步的,因此需要使用回调函数来处理返回值。
- 由于插件的不同组件之间是通过消息传递进行通信的,因此需要注意消息的发送和接收的时序关系,以避免出现数据丢失或不一致的情况。
- 在使用 Message Passing API 时,需要谨慎处理数据的安全性,避免恶意代码对插件进行攻击。
Message Passing API 主要提供了以下内容 :
字段名 | 描述 |
---|---|
chrome.runtime.sendMessage() | 用于向指定的扩展程序或 content script 发送消息 |
chrome.runtime.onMessage() | 用于监听来自指定的扩展程序或 content script 发送的消息 |
chrome.runtime.connect() | 用于在扩展程序或 content script 之间建立长连接,以便进行双向通信 |
chrome.runtime.onConnect() | 用于监听来自扩展程序或 content script 建立的连接请求,并返回连接对象以便进行通信 |
二. 主要方法
1. chrome.runtime.sendMessage()
chrome.runtime.sendMessage()
用于向插件的后台页面发送消息,并接收响应,它的作用是将消息发送到插件的后台页面,并等待后台页面的响应。在发送消息时,我们可以传递一个包含要发送数据的JavaScript对象,而在接收响应时,则需要提供一个回调函数来处理返回的数据。
在Google插件开发中,我们通常需要从Content Script中向后台页面发送请求或获取数据,并根据返回值来进行相应的处理。此时,chrome.runtime.sendMessage
方法就可以派上用场了。
它共有三个参数:
字段名 | 描述 |
---|---|
message | 要发送的消息内容,可以是任何JavaScript对象 |
responseCallback | 接收响应的回调函数,该函数会在后台页面返回响应时被调用,可以访问后台页面返回的任何JavaScript对象 |
options | 可选参数,用于指定消息发送的目标(例如,指定插件ID)和其他设置 |
需要注意的是,由于Content Script与后台页面运行在不同的JavaScript环境中,因此它们之间无法直接共享变量和函数。如果需要在Content Script和后台页面之间传递数据,可以使用JSON序列化、解析或者Chrome扩展的原生消息格式来进行数据传输。
下面是一个使用chrome.runtime.sendMessage
方法向后台页面发送消息的示例代码:
// 向后台页面发送消息,请求获取设置信息
chrome.runtime.sendMessage({action: 'getSettings'}, function(response) {
console.log('获取到的设置信息为:', response);
});
该示例代码中,首先使用chrome.runtime.sendMessage
方法向后台页面发送一个JavaScript对象{action: 'getSettings'}
作为请求参数,然后在回调函数中接收后台页面返回的响应数据response并输出到控制台。
2. chrome.runtime.onMessage()
chrome.runtime.onMessage
是 Message Passing API 中用于监听来自其他扩展程序或 content script 发送的消息的事件。
具体来说,当其他扩展程序或 content script 调用 chrome.runtime.sendMessage()
发送消息时,可以通过监听 chrome.runtime.onMessage 事件来接收到这些消息。当收到消息后,可以根据消息的内容执行相应的操作,例如修改页面内容、向页面注入脚本等。
它共有三个参数:
字段名 | 描述 |
---|---|
callback | 接收到消息时的回调函数,必选参数 |
options | 消息接收选项,可选参数 |
responseCallback | 发送响应消息时的回调函数,可选参数。如果不传递该参数,则收到消息后不发送响应 |
以下是一个简单的代码示例,演示了如何在 content script 中监听 chrome.runtime.onMessage 事件,接收来自 popup 的消息并执行相应的操作:
// content_script.js
// 监听来自其他扩展程序或 content script 发送的消息
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
// 根据消息内容执行相应的操作
if (request.action === 'modifyPageContent') {
document.body.style.backgroundColor = 'pink';
sendResponse({ message: 'Page content modified!' });
}
});
在上面的代码中,我们在 content script 中注册了 chrome.runtime.onMessage 事件的监听器,当收到 chrome.runtime.sendMessage()
发送过来的消息时,会执行回调函数。在回调函数中,我们判断消息内容的 action 属性,如果是 'modifyPageContent'
,则将页面的背景色修改为粉色,并通过 sendResponse 方法向消息发送方返回响应消息,内容为 { message: 'Page content modified!' }
。
需要注意的事项 ⚠️
- 在监听 chrome.runtime.onMessage 事件时,需要使用
chrome.runtime.onMessage.addListener()
方法注册监听器。 - 在回调函数中,可以通过 request 参数获取到消息的内容,通过 sender 参数获取到消息发送方的信息,通过 sendResponse 方法向消息发送方返回响应消息。
- 当使用 sendResponse 方法向消息发送方返回响应消息时,需要保证回调函数返回 true 值,否则消息发送方可能无法接收到响应消息。
- 当使用
chrome.runtime.sendMessage()
发送消息时,需要注意消息的格式,只支持序列化的对象类型。 - 在 content script 中,需要在 manifest.json 文件中声明相应的权限,才能与其他扩展程序或页面进行通信。例如:
{
"name": "My Extension",
"version": "1.0",
"manifest_version": 3,
"permissions": [
"tabs",
"activeTab",
"scripting",
"<all_urls>"
],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content_script.js"]
}
]
}
在上面的示例中,我们声明了 "permissions"
中的 "scripting"
权限和 "content_scripts"
中的 "matches"
,使得 content script 能够与其他扩展程序或页面进行通信。
3. chrome.runtime.connect()
chrome.runtime.onMessage
用于在扩展程序中的不同脚本之间传递消息。具体来说,它允许扩展程序中的一个脚本向另一个脚本发送消息,并且可以在发送后接收响应消息。
使用该方法时,需要指定一个回调函数作为参数,当接收到消息时会调用该回调函数。回调函数会接收三个参数,分别是传递的消息、发送者信息以及发送响应消息的函数。其中,发送响应消息的函数是可选的。
它的应用场景非常广泛,例如:
- 在 popup 页面与 content script 之间传递消息。
- 在 background script 与 content script 之间传递消息。
- 在不同的 content script 之间传递消息。
- 在 options 页面与 background script 之间传递消息。
下面是一个简单的示例,演示了如何在 popup 页面和 content script 之间传递消息,并接收响应消息:
popup.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Popup</title>
</head>
<body>
<button id="btn">发送消息</button>
<script src="popup.js"></script>
</body>
</html>
popup.js:
const btn = document.getElementById('btn');
// 点击按钮时向 content script 发送消息
btn.addEventListener('click', () => {
chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
chrome.tabs.sendMessage(tabs[0].id, { greeting: 'Hello' }, response => {
console.log(response.farewell);
});
});
});
content_script.js:
// 接收消息
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
console.log(message.greeting);
// 发送响应消息
sendResponse({ farewell: 'Goodbye' });
});
在上述示例中,当用户在 popup 页面点击按钮时,会向当前活动的标签页发送一条消息,消息的内容为 { greeting: 'Hello' }
。标签页中的 content script 会接收到该消息,并打印出 Hello。同时,content script 会向 popup 页面发送一条响应消息,消息的内容为 { farewell: 'Goodbye' }
。popup 页面会接收到该响应消息,并打印出 Goodbye。
需要注意的事项 ⚠️
- 消息的接收者需要在 manifest.json 中注册对应的消息处理函数,否则消息将被忽略;
- 消息处理函数需要返回一个 Promise 或者是一个普通的值,以便发送者能够获取到处理结果;
- 由于消息是异步传递的,发送者需要在发送消息后等待接收者的响应,这可以通过使用 Promise 或者回调函数来实现。
三. 应用示例
下面我们来实现一个 Google 插件,以帮助您更好地理解 Message Passing API 的作用。该插件可以帮助用户在不离开当前页面的情况下,快速搜索他们所需的内容。简单来说,就是用户可以选择一个单词或一段文字,然后通过右键点击弹出的菜单选择“Search”,该插件将在新的选项卡中打开一个搜索引擎,并使用所选的文本作为搜索关键词。
我们来看下效果:
那我们就开始来实现这个效果,我们先在扩展程序根目录下创建 manifest.json 文件,并添加以下配置:
{
"manifest_version": 2,
"name": "Quick Search",
"version": "1.0",
"description": "A quick search tool for selected text",
"background": {
"scripts": ["background.js"]
},
"permissions": ["contextMenus"],
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content.js"]
}]
}
我们在 "permissions"
字段中声明了一个权限 "contextMenus"
,表示扩展程序需要访问浏览器上下文菜单(右键菜单)。在 "content_scripts"
字段中定义了一个脚本文件 "content.js",该脚本会在扩展程序的内容页(所有 URL)中运行,用于实现具体的功能。
接下来我们新建background.js文件:用于处理右键点击事件并与内容脚本通信。
chrome.contextMenus.create({
title: "Search",
contexts: ["selection"],
onclick: function (info, tab) {
chrome.tabs.sendMessage(tab.id, { action: "search", selection: info.selectionText });
}
});
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.action === "openTab") {
chrome.tabs.create({ url: request.url });
}
});
第一步:创建了右键菜单
当用户在浏览器中选中文本后,可以右键点击,选择 "Search" 菜单项,触发搜索功能。这个功能通过使用 chrome.contextMenus.create()
函数来创建右键菜单项,传递一个对象参数,其中包括菜单项的标题、上下文(只有在选中文本时才显示该菜单项)以及点击时触发的回调函数。回调函数通过 chrome.tabs.sendMessage()
函数将所选文本发送到扩展程序的内容脚本中进行处理。
第二步:接收消息并打开新标签页
当扩展程序的内容脚本接收到 "openTab" 消息时,会触发 chrome.runtime.onMessage.addListener()
函数注册的回调函数,该函数接收一个请求对象 request,如果请求对象的 action 属性为 "openTab"
,则通过 chrome.tabs.create()
函数打开一个新的标签页,加载请求的 URL。这个功能用于在扩展程序的内容脚本中打开搜索结果页面,以供用户查看。
接下来我们再新建一个content.js文件:用于从内容页面与后台页面通信,以及在新的选项卡中打开搜索引擎。
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.action === "search") {
var searchUrl = "https://www.google.com/search?q=" + encodeURIComponent(request.selection);
chrome.runtime.sendMessage({ action: "openTab", url: searchUrl });
}
});
第一步:接收消息并处理搜索请求
当扩展程序的内容脚本接收到 "search" 消息时,会触发 chrome.runtime.onMessage.addListener()
函数注册的回调函数,该函数接收一个请求对象 request,如果请求对象的 action 属性为 "search",则会从所选文本构造一个 Google 搜索 URL,将该 URL 发送给扩展程序的后台脚本,通过 chrome.runtime.sendMessage()
函数发送一个 "openTab" 消息,并携带搜索 URL 作为参数。
第二步:发送消息并打开新标签页
当扩展程序的后台脚本接收到 "openTab" 消息时,会触发 chrome.runtime.onMessage.addListener()
函数注册的回调函数,该函数接收一个请求对象 request,如果请求对象的 action 属性为 "openTab",则通过 chrome.tabs.create()
函数打开一个新的标签页,加载请求的 URL。这个功能用于在扩展程序的后台脚本中打开搜索结果页面,以供用户查看。
以上就是整个插件的代码,当您选中文本并右键单击时,就会看到“Search”菜单。选择该菜单后,该插件将在新的选项卡中打开一个Google搜索引擎,并使用您选择的文本作为搜索关键词。
本节中,我们详细了解了 Message Passing API 在 Google Chrome 插件开发中的重要性和作用。我们理解了它的概念、运行方式和可配置项,并了解了如何实现跨页面通信和数据交换。
Message Passing API 为插件开发提供了强大的功能,使不同页面之间的通信变得简单而高效。通过合理地使用该API,我们可以实现更多交互和功能扩展,提升用户体验。
本节课程源码 📥
链接: pan.baidu.com/s/14URANeO8… 提取码: 8888