keywords: Chrome 插件开发, 消息传递机制, 背景脚本, 内容脚本, popup 界面, 通信管道


在 Chrome 插件的开发过程中,消息传递机制是实现不同部分之间通信的关键。无论是从背景脚本到内容脚本,还是从 popup 界面到背景脚本,都需要建立有效的通信管道。本章将详细介绍如何实现这些通信机制。

背景脚本与内容脚本通信

1. 背景脚本background.js的编写

背景脚本在 Chrome 插件的生命周期中始终保持运行状态,用于处理无法由内容脚本完成的任务。首先,我们需要在项目中创建 background.js 并添加到 manifest.json 文件中。

background.js

  1. // background.js
  2. chrome.runtime.onInstalled.addListener(() => {
  3. console.log("插件已安装");
  4. });
  5. chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  6. console.log("收到消息: ", message);
  7. sendResponse({ status: "消息已收到" });
  8. });

2. 更新manifest.json文件

确保在 manifest.json 中声明了 background.js

manifest.json

  1. {
  2. "manifest_version": 3,
  3. "name": "翻译和词典插件",
  4. "version": "1.0",
  5. "background": {
  6. "service_worker": "background.js"
  7. },
  8. "permissions": ["activeTab", "scripting"],
  9. "action": {
  10. "default_popup": "popup.html",
  11. "default_icon": {
  12. "16": "images/icon-16.png",
  13. "48": "images/icon-48.png",
  14. "128": "images/icon-128.png"
  15. }
  16. },
  17. "content_scripts": [
  18. {
  19. "matches": ["<all_urls>"],
  20. "js": ["content.js"]
  21. }
  22. ]
  23. }

处理短连接与长连接

短连接

短连接适用于简单的请求响应模式。例如,当用户点击某个按钮时,发送一个请求,获得响应后进行相应操作。

popup.js

  1. // popup.js
  2. document.getElementById("sendMessage").addEventListener("click", () => {
  3. chrome.runtime.sendMessage({ greeting: "Hello" }, (response) => {
  4. console.log("收到响应:", response);
  5. });
  6. });

长连接

长连接适用于需要持续通信的场景。我们可以使用 chrome.runtime.connectchrome.runtime.onConnect 建立长连接。

content.js

  1. // content.js
  2. const port = chrome.runtime.connect({ name: "knockknock" });
  3. port.postMessage({ joke: "Knock knock" });
  4. port.onMessage.addListener((msg) => {
  5. console.log("背景脚本响应: ", msg);
  6. });

background.js 的更新

  1. // background.js
  2. chrome.runtime.onConnect.addListener((port) => {
  3. console.assert(port.name === "knockknock");
  4. port.onMessage.addListener((msg) => {
  5. if (msg.joke === "Knock knock") {
  6. port.postMessage({ question: "Who's there?" });
  7. }
  8. });
  9. });

实现选中文本的传递

接下来,我们将实现一个简单的功能:获取网页中用户选中的文本,并将其传递给背景脚本处理。

1. 添加选中文本获取功能

content.js 中添加以下代码,获取选中文本并发送给背景脚本。

content.js

  1. // content.js
  2. document.addEventListener("mouseup", () => {
  3. const selectedText = window.getSelection().toString().trim();
  4. if (selectedText.length > 0) {
  5. chrome.runtime.sendMessage({ text: selectedText }, (response) => {
  6. console.log("背景脚本响应:", response);
  7. });
  8. }
  9. });

2. 背景脚本处理选中文本

background.js 中处理接收到的选中文本。

background.js

  1. // background.js
  2. chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  3. if (message.text) {
  4. console.log("选中文本:", message.text);
  5. // 这里可以进行进一步处理,例如调用 API 翻译文本
  6. sendResponse({ status: "文本已收到并处理" });
  7. }
  8. });

通过以上步骤,我们成功实现了从内容脚本到背景脚本的消息传递,并处理了选中文本的传递。这种机制为插件的功能扩展提供了无限可能。