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