过渡到浏览器命名空间

从 Chrome 148 开始,除了现有的 chrome 命名空间之外,所有 Chrome 扩展程序 API 都可在 browser 命名空间下使用。例如,browser.tabs.create({})chrome.tabs.create({}) 是等效的。

无论您在何处调用扩展程序 API(包括内容脚本、Service Worker 和屏幕外文档),都可以使用该命名空间。它指向与 chrome 相同的 API 对象,因此 chrome.tabs === browser.tabs

browser 命名空间源自 WebExtensions Community Group (WECG) 的工作,这是一个 W3C 社区群组,浏览器供应商在此群组中就共享扩展程序 标准进行协作。chrome 命名空间不会消失;这两个命名空间将继续正常运行。

决定是否采用浏览器命名空间

如果您使用的是 webextension-polyfill,请跳到 针对 polyfill 用户的说明,然后再进行任何其他更改 ,因为答案对您来说是不同的。

如果您要构建新的扩展程序,请将 minimum_chrome_version 设置为 "148" 并无条件使用 browser;您可以就此停止阅读。本部分其余内容适用于决定如何采用的现有扩展程序。

检查用户使用的 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,您就可以移除 polyfill 依赖项。

其他功能

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 模式将继续有效,因此现有代码无需更改。