从 Chrome 148 开始,除了现有的 chrome 命名空间之外,所有 Chrome 扩展程序 API 都可在 browser 命名空间下使用。例如,browser.tabs.create({}) 和 chrome.tabs.create({}) 是等效的。
您可以在任何可以调用扩展程序 API 的位置使用该命名空间,包括内容脚本、服务工作器和离屏文档。它指向与 chrome 相同的 API 对象,因此为 chrome.tabs === browser.tabs。
browser 命名空间源自 WebExtensions 社区组 (WECG) 的工作,这是一个 W3C 社区组,浏览器供应商在此组中协作制定共享扩展标准。chrome 命名空间不会消失;这两个命名空间将继续有效。
决定是否采用浏览器命名空间
如果您使用的是 webextension-polyfill,请先跳到针对 Polyfill 用户的注意事项,然后再进行其他更改,因为您的情况有所不同。
如果您要构建新扩展程序,请将 minimum_chrome_version 设置为 "148" 并无条件使用 browser;您可以到此为止。本部分其余内容适用于正在考虑如何采用新 API 的现有扩展程序。
查看用户使用的是哪个 Chrome 版本
如果您有现有扩展程序,请在切换之前检查用户正在运行的 Chrome 版本。Chrome 会自动更新,但有些用户会停用更新,还有些用户使用的是无法运行最新版本的旧设备。 使用您自己的分析数据进行确认。如果您尚未设置分析,请参阅使用 Google Analytics 4 监控扩展程序的性能,开始设置分析。
然后,选择一个路径:
无条件采用
在清单中设置 minimum_chrome_version,并无条件使用 browser - 无需运行时保护:
{
"minimum_chrome_version": "148"
}
提高 minimum_chrome_version 时,请使用分阶段发布。如果出现问题,您可以在 Chrome 应用商店中回滚扩展程序。
使用运行时防护
在扩展程序的启动代码中尽早添加以下代码段,然后再在其他任何位置引用 browser:
if (!globalThis.browser) {
globalThis.browser = chrome;
// Consider firing an analytics event here to measure how often
// your users hit this fallback path.
}
这使得 browser 在早期版本中成为 chrome 的别名,因此您代码的其余部分可以无条件地使用 browser。
面向 Polyfill 用户的说明
如果您的扩展程序使用 webextension-polyfill,则在 Chrome 148 及更高版本中会变为无操作。如果 browser 已定义,polyfill 会跳过封装,假设宿主浏览器已提供该 API。
之前尝试在 Chrome 136 中发布命名空间,但因以下原因而回滚:在定义了新的 browser 后,polyfill 停止了封装,但 Chrome 的 browser.runtime.onMessage 尚不支持返回 Promise 的监听器,而 polyfill 一直在提供这种监听器。依赖于该模式的扩展程序已损坏。Chrome 148 将命名空间和返回原生 Promise 的 onMessage 监听器一起提供,以避免出现此间隙。
一旦用户群迁移到 Chrome 148,您就可以移除该填充依赖项。
其他功能
runtime.sendMessage 中的异步响应
在 Chrome 148 中,runtime.onMessage 监听器可以直接返回 Promise 以发送异步响应。无论您是使用 chrome.* 还是 browser.* 调用它,此方法都有效。
以前,异步响应的唯一方法是从监听器返回字面值 true,然后稍后调用 sendResponse:
// Old pattern - requires returning true to keep the channel open
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
fetch('https://example.com')
.then(response => sendResponse({ statusCode: response.status }));
return true; // keeps the message channel open for the async response
});
现在,您可以直接返回 Promise(或使用 async 函数):
// New pattern - return a promise or use async/await
browser.runtime.onMessage.addListener(async (message, sender) => {
const response = await fetch('https://example.com');
return { statusCode: response.status };
});
return true 模式继续有效,因此现有代码无需更改。