chrome contents.js 与 background.js的通信方式详解

最近在做一个https网站与局域网设备服务器通信的浏览器插件,用于转发https到http,代理websocket。研究了一下插件的通信。


✅ 简明回答:content.jsbackground.js 的通信方式有两种

通信方式是否双向是否长连接适用场景
chrome.runtime.sendMessage / onMessage✅单次请求-响应❌短连接(一次性)简单、一次性的请求
chrome.runtime.connect / onConnect + port.postMessage✅双向✅支持持久长连接需要持续通信,如大文件、WebSocket代理、流式传输等

🧩 1. chrome.runtime.sendMessage / chrome.runtime.onMessage

作用:

发送一次性消息(请求 -> 响应)

示例:

content.js 发消息到 background.js
chrome.runtime.sendMessage({ type: "ping" }, (response) => {
  console.log("收到 background 响应:", response);
});
background.js 中接收:
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.type === "ping") {
    sendResponse({ reply: "pong from background" });
  }
  return true; // 保持异步响应有效
});

适合: 请求设备状态、获取 token、简单查询等。


🔁 2. chrome.runtime.connect / onConnect + port.postMessage

作用:

建立持久连接,可用于持续数据交互,如:

  • 分片上传大文件
  • WebSocket 代理中转
  • 实时日志或状态推送

示例:

content.js 中发起连接:
const port = chrome.runtime.connect({ name: "toocaa-page" });

port.postMessage({ type: "file-chunk", data: ... });

port.onMessage.addListener((msg) => {
  console.log("收到 background 推送:", msg);
});
background.js 中监听连接:
chrome.runtime.onConnect.addListener((port) => {
  if (port.name === "toocaa-page") {
    port.onMessage.addListener((msg) => {
      if (msg.type === "file-chunk") {
        // 收到文件片段
      }

      // 发送响应或推送消息
      port.postMessage({ type: "upload-status", progress: "50%" });
    });
  }
});

适合: 文件流、持续上传、插件与网页实时交互。


❗重要提醒:

区别总结:

特性sendMessageconnect / port
连接生命周期一次性,立即断开保持连接,直到主动断开
数据大小建议小数据可用于流式数据
适用对象content ↔ background,popup ↔ background 等content ↔ background 持续通信
是否支持多端口❌每次调用独立✅ 多个 port 可共存

✅ 建议使用方式(经验)

场景推荐方式
上传文件 < 5MB,参数少sendMessage
上传大文件、分片、实时回传上传进度connect + port.postMessage
页面只需发送一次请求,比如查询状态sendMessage
插件与页面持续通讯(如 WebSocket 中继)connect

网页直接与background.js 直接通讯的方式

在 Chrome 插件中,网页与 background.js(或 service worker)之间的通信是否必须经过 content.js,要根据情况区分。下面详细解释各种通信方式:


✅ 结论:

网页想要直接与 background.js 通信,不必须经过 content.js,但前提是网页主动连接插件。


📌 一、三种通信方式汇总

方式是否需要 content.js 中转说明
1. ✅ 网页 → content.jsbackground.js最常见,用 postMessage + runtime.sendMessage
2. ✅ 网页 → background.js(通过 chrome.runtime.connectchrome.runtime.sendMessage只限网页主动发起插件必须有 externally_connectable
3. ✅ 插件注入脚本 → 网页 → content.jsbackground.js一种变种,脚本非网页自身控制,而是插件注入

🧠 二、网页直接与 background.js 通信的条件

1. 使用 chrome.runtime.sendMessagechrome.runtime.connect

网页可以直接调用如下代码:

// 网页中(非插件脚本)
chrome.runtime.sendMessage(
  '扩展ID',
  { greeting: 'hello' },
  response => {
    console.log('收到来自插件的回应:', response);
  }
);

2. 需要插件在 manifest.json 中声明权限:

"externally_connectable": {
  "matches": ["https://example.com/*"]  // 或 ["<all_urls>"](调试用)
}

否则网页是没有权限连接插件的,调用会失败。

3. 插件 background.js 需要监听来自网页的连接:

chrome.runtime.onMessageExternal.addListener(
  function(request, sender, sendResponse) {
    console.log('收到网页的消息:', request);
    sendResponse({ received: true });
  }
);

❗ 注意事项:

  • 插件必须知道自己的 ID(或者网页知道插件的 ID),才能发送消息。
  • 多数情况下推荐使用 content.js 中转,这样可以安全地监听网页中的 JS 行为,并与插件通信。

✅ 推荐使用场景总结:

场景是否推荐使用 content.js 中转
插件控制网页,监听按钮、脚本注入等✅ 是
网页是你自己开发的网站,想和插件通信❌ 可省略 content.js,用 runtime.sendMessage
插件为通用扩展,不知道网页是否可信✅ 用 content.js 更安全

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拿我格子衫来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值