第三部分 — 服务工作者(后台)chrome.runtime 是什么(在 MV3 的说法中)

chrome.runtime 是扩展内的"粘合剂" API:

  • 生命周期事件(安装/更新)

  • 身份 (runtime.id, getURL)

  • 轻量级消息入口点

  • 通过 chrome.runtime.lastError 的错误处理层(针对回调 API)

如果从 MV2 迁移过来:将 chrome.runtime 视作 稳定协调层, 位于 UI 页面、服务工作者、内容脚本之间(可选地) 与离屏文档之间。

7.2 runtime.id, getURL,以及环境假设

javascript 复制代码
console.log("extension id:", chrome.runtime.id); 
console.log("options url:", chrome.runtime.getURL("options.html"));

注意事项:

  • 除非在企业部署流程中,否则不要硬编码扩展ID。

  • 对于内部资源,请使用 getURL()。 它可以适应打包差异。

7.3 实际使用的 onInstalled 细节

javascript 复制代码
chrome.runtime.onInstalled.addListener((details) => {
  console.log("onInstalled:", details.reason, details.previousVersion);

  if (details.reason === "install") {
    // One-time setup: defaults, onboarding, etc.
  }

  if (details.reason === "update") {
    // Migration: version-based transforms.
  }
});

设计规则: 数据迁移必须是幂等的,并且在需要时可以安全地重新运行。

7.4 消息入口点:onMessage(以及异步陷阱)

最小模式(异步响应):

javascript 复制代码
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  (async () => {
    if (msg.type !== "PING") return;
    sendResponse({ ok: true, from: "sw" });
  })().catch((err) => {
    sendResponse({ ok: false, error: String(err) });
  });

  // Critical in MV3: keep the channel open for async.
  return true;
});
复制代码

** Pitfalls:**

  • 忘记添加 return true → 间歇性"消息通道关闭"失败。

  • 不验证 sender → 多个上下文发送消息时的安全/逻辑漏洞。

7.5 始终验证 sender(最小安全检查)

javascript 复制代码
function assertSender(sender) {
  // Example: only accept messages from your own extension pages.
  if (sender.id !== chrome.runtime.id) {
    throw new Error("Unexpected sender.id");
  }
}

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  try {
    assertSender(sender);
    sendResponse({ ok: true });
  } catch (e) {
    sendResponse({ ok: false, error: String(e) });
  }
});

7.6 回调错误:chrome.runtime.lastError(当适用时)

规则: 只在回调内部检查 lastError。

javascript 复制代码
chrome.runtime.getPlatformInfo((info) => {
  if (chrome.runtime.lastError) {
    console.error(chrome.runtime.lastError.message);
    return;
  }
  console.log(info);
});
复制代码

陷阱: 在回调之外检查 lastError 没有意义。

7.7 connect vs sendMessage(决策点)

  • 使用 sendMessage 进行请求/响应操作。

  • 当你需要以下功能时使用 connect (端口):

  • 流式进度

  • 长期协调

  • 重连逻辑(特别是在 SW 重启时)

(端口在第四部分有深入介绍。)

最小示例

一个最小的 MV3 安全异步消息处理器(适合作为模板):

javascript 复制代码
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  (async () => {
    if (msg?.type !== "PING") return;
    sendResponse({ ok: true });
  })().catch((err) => sendResponse({ ok: false, error: String(err) }));
  return true; // keep channel open for async
});

常见陷阱

  • 依赖隐式的状态(全局变量)而不是持久化的存储

  • 假设 MV3 提供的时间/生命周期保证实际上并不提供

  • 过度请求权限/宿主访问

7.8 检查清单

  • 不要硬编码扩展 ID(除非企业版)

  • onInstalled 的迁移操作是幂等的

  • 所有异步 onMessage 处理函数都返回 true

  • 验证 sender 至少通过 sender.id

  • 对于回调 API:在回调中检查 runtime.lastError

7.9 参考

相关推荐
回眸&啤酒鸭1 小时前
【回眸】OpenSwarm 多智能体协作系统实战指南
大数据·前端·人工智能
用户69371750013841 小时前
2026,程序员的时代拐点到了
android·前端·后端
大龄秃头程序员1 小时前
一次 iBeacon + BLE 无感解锁方案的实现记录
前端
小兔子1 小时前
Python 的 GIL 与 free-threading:3.13 之后「去 GIL」走到哪一步了
前端
IT_陈寒1 小时前
SpringBoot自动配置差点让我加班到凌晨
前端·人工智能·后端
guslegend3 小时前
脚手架原理与本地调试:从 bin 软链接到 npm link
前端·npm·node.js·脚手架·前端工程化
小宋10213 小时前
A2UI从零实战:Agent安全生成交互界面与事件回传
javascript·人工智能·安全·交互
大包子3 小时前
structuredClone vs lodash.cloneDeep:核心差异与选型指南
javascript·vue.js
海码事务所3 小时前
Google Play 新个人开发者账号上架指南:12 人连续 14 天封闭测试怎么做?
前端
田威AI3 小时前
图片内文字翻译的规格:输入输出、保真、自动化、时间与费用
前端·计算机视觉