第三部分 — 服务工作者(后台)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(除非企业版)

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

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

  • chrome.runtime(官方): chrome.runtime

  • 消息概览(官方): Message passing

相关推荐
freewlt3 小时前
前端性能优化实战:从 Lighthouse 分数到用户体验的全面升级
前端·性能优化·ux
小小亮013 小时前
Next.js基础
开发语言·前端·javascript
华洛3 小时前
我用AI做了一个48秒的真人精品漫剧,不难也不贵
前端·javascript·后端
Amumu121384 小时前
Js:正则表达式(二)
开发语言·javascript·正则表达式
Novlan14 小时前
我把 Claude Code 里的隐藏彩蛋提取出来了——零依赖的 ASCII 虚拟宠物系统
前端
Sgf2274 小时前
ES8(ES2017)新特性完整指南
开发语言·javascript·ecmascript
IAUTOMOBILE4 小时前
Python 流程控制与函数定义:从调试现场到工程实践
java·前端·python
好大哥呀4 小时前
C++ Web 编程
开发语言·前端·c++
爱学习的小仙女!5 小时前
面试题 前端(一)DOCTYPE作用 标准模式与混杂模式区分
前端·前端面试题
小小小小宇6 小时前
前端转后端基础- 变量和类型
前端