从 Chrome 109 开始,为了在从后台页面向扩展程序 Service Worker 过渡的过程中替换掉后台功能,开发者可以使用 chrome.offscreen
API 和清单权限。请求此权限可以创建使用 DOM API 的屏幕外文档,而不会突兀地打开新窗口或标签页,并会干扰用户体验。chrome.offscreen
API 现已可在 Chrome 扩展程序中使用。
在 Chromium 中,Manifest V3 扩展程序是基于 Service Worker 的,但 Service Worker 无法像基于文档的完整页面(包括后台和事件页面)一样支持相同的 API 和机制。此外,使用内容脚本访问网页上的 DOM API 会使该扩展程序逐页应用不同的内容安全政策。为帮助解决此问题,我们引入了屏幕外文档功能,以允许 Manifest V3 扩展程序在运行时通过专用 API 打开最小、范围且无需授权的屏幕外文档,从而支持 DOM 相关功能和 API。
功能信息
由于屏幕外文档是专为处理 Service Worker 不支持的用例(例如音频播放)而设计的,因此此页面的生命周期以及将获得的权限与扩展 Service Worker 的权限是分开的。该页面的生命周期机制与 Manifest V2 中的事件页面类似,原因是页面在停止执行操作后会被销毁。此外,用户代理可能会针对指定用途对生命周期施加进一步限制。
屏幕外文档旨在填补只有 DOM API 可访问的 API 中的缺口;因此,在此上下文中不需要直接公开扩展 API。为了降低扩展程序将其用作“后台页面替换”的可能性,系统仅向屏幕外文档公开 chrome.runtime
Messaging API。(开发者还可以使用网络消息传递,方法是通过 Service Worker 将屏幕外文档声明为 Client)。由于某些用例(尤其是网站抓取)需要访问跨源框架,因此我们允许这些文档按照与目前扩展程序页面相同的规则嵌入跨源框架。在屏幕外文档中,扩展程序指定的内容脚本能够在这些框架中运行,以爬取任何必要内容,就像处理任何普通网页一样。
原因和要求目的
制作屏幕外文档需要说明原因和进一步的理由。API 参考文档中列出了这些原因,它们以不同的方式处理文档的生命周期。例如,对于打开以播放音频的文档,目前其生命周期应用的规则与打开剪贴板管理的文档不同。您还可以在理由中进一步详细说明屏幕外文档的用途,该字符串是开发者编写的字符串,而不是会对文档产生影响的参数。 随着开发者分享反馈和使用案例,API 可能会添加更多原因。
展望未来
为便于实施,此 API 的第一个版本仅支持每个扩展程序、每个配置文件一次显示一个页面。在未来的版本中,我们可能会放宽这一限制,以支持多个网页。目前,如果扩展程序在分屏模式下使用有效的无痕模式运行,则普通个人资料和无痕模式个人资料可以各自有一个屏幕外文档。 我们还计划在以后为扩展工作器提供 DOM 功能。您可以将使用屏幕外 API 的函数与 Service Worker 中具有注释的等效函数(以便日后交换)配对,从而让您的扩展程序为未来做好准备。
// Solution 1 - Service workers cannot directly interact with
// the system clipboard. To work around this, we'll create an offscreen
// document and pass the data we want to write to the clipboard.
async function addToClipboard(value) {
await chrome.offscreen.createDocument({
url: 'offscreen.html',
reasons: [chrome.offscreen.Reason.CLIPBOARD],
justification: 'Write text to the clipboard.',
});
}
// Solution 2 – Once extension service workers can use the Clipboard API,
// replace the offscreen document based implementation with something like this
async function addToClipboardV2(value) {
navigator.clipboard.writeText(value);
}
此外,当向 Service Worker 添加 DOM 功能和 API 时,创建文档的原因列表将根据 Service Worker 的当前状态以及使用屏幕外文档的原因增加或减少。
总结
屏幕外文档支持需要 DOM 或窗口交互访问权限的扩展程序,而这些访问目前在 Service Worker 中无法实现。它还提供了一种灵活的方法,您可以在其中添加新的用例,并移除未来解决的用例。 扩展程序应该针对具体用例采用提议的屏幕外文档 API,并且扩展程序的主要后台上下文应保持在清单中指定的 Service Worker。屏幕外文档不应用于存储主要扩展程序逻辑,因为它的 API 访问权限有限。屏幕外文档的生命周期与创建它的 Service Worker 无关。我们将在单独的博文中介绍与扩展程序中的 Service Worker 生命周期相关的 Service Worker 生命周期注意事项和用例。 随着功能和 API 不断添加到 Service Worker 本身,使用屏幕外文档的原因将会出现波动。我们热切希望听到开发者的反馈。