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

相关推荐
|晴 天|2 小时前
Vue 3 + TypeScript + Element Plus 博客系统开发总结与思考
前端·vue.js·typescript
猫3283 小时前
v-cloak
前端·javascript·vue.js
AC赳赳老秦3 小时前
OpenClaw二次开发实战:编写专属办公自动化技能,适配个性化需求
linux·javascript·人工智能·python·django·测试用例·openclaw
旷世奇才李先生3 小时前
Vue 3\+Vite\+Pinia实战:企业级前端项目架构设计
前端·javascript·vue.js
Ulyanov3 小时前
《PySide6 GUI开发指南:QML核心与实践》 第二篇:QML语法精要——构建声明式UI的基础
java·开发语言·javascript·python·ui·gui·雷达电子对抗系统仿真
聚美智数4 小时前
企业实际控制人查询-公司实控人查询
android·java·javascript
SoaringHeart4 小时前
Flutter进阶:用OverlayEntry 实现所有弹窗效果
前端·flutter
IT_陈寒6 小时前
Vite静态资源加载把我坑惨了
前端·人工智能·后端
herinspace6 小时前
管家婆实用贴-如何分离和附加数据库
开发语言·前端·javascript·数据库·语音识别
小码哥_常6 小时前
从MVC到MVI:一文吃透架构模式进化史
前端