chrome.offscreen

说明

使用 offscreen API 创建和管理屏幕外文档。

权限

offscreen

如需使用 Offscreen API,请在扩展程序清单中声明 "offscreen" 权限。例如:

{   "name": "My extension",   ...   "permissions": [     "offscreen"   ],   ... } 

可用性

Chrome 109 及更高版本 MV3 及更高版本

概念和用法

Service worker 没有 DOM 访问权限,并且许多网站都有内容安全政策来限制内容脚本的功能。借助 Offscreen API,扩展程序可以在隐藏文档中使用 DOM API,而不会通过打开新窗口或标签页来中断用户体验。runtime API 是离屏文档支持的唯一扩展程序 API。

作为屏幕外文档加载的页面与其他类型的扩展程序页面不同,其处理方式也不同。 扩展程序的权限会沿用到离屏文档,但对扩展程序 API 的访问权限有限制。例如,由于 chrome.runtime API 是离屏文档支持的唯一扩展服务 API,因此必须使用该 API 的成员来处理消息传递。

以下是离屏文档与常规网页的不同之处:

  • 离屏文档的网址必须是与扩展程序捆绑的静态 HTML 文件。
  • 无法聚焦屏幕外的文档。
  • 屏幕外文档是 window 的实例,但其 opener 属性的值始终为 null
  • 虽然扩展程序软件包可以包含多个屏幕外文档,但已安装的扩展程序一次只能打开一个屏幕外文档。如果扩展程序在分屏模式下运行,且无痕式浏览个人资料处于活动状态,则常规个人资料和无痕式浏览个人资料各自可以有一个屏幕外文档。

使用 chrome.offscreen.createDocument()chrome.offscreen.closeDocument() 创建并关闭屏幕外文档。createDocument() 需要提供文档的 url、原因和理由:

chrome.offscreen.createDocument({   url: 'off_screen.html',   reasons: ['CLIPBOARD'],   justification: 'reason for needing the document', }); 

原因

如需查看有效原因的列表,请参阅原因部分。原因是在创建文档时设置的,用于确定文档的有效期。AUDIO_PLAYBACK 原因会将文档设置为在 30 秒后关闭,且不播放音频。所有其他原因都不会设置使用期限限制。

示例

维护屏幕外文档的生命周期

以下示例展示了如何确保存在屏幕外文档。setupOffscreenDocument() 函数会调用 runtime.getContexts() 来查找现有的屏幕外文档,或者在文档尚不存在时创建该文档。

let creating; // A global promise to avoid concurrency issues async function setupOffscreenDocument(path) {   // Check all windows controlled by the service worker to see if one   // of them is the offscreen document with the given path   const offscreenUrl = chrome.runtime.getURL(path);   const existingContexts = await chrome.runtime.getContexts({     contextTypes: ['OFFSCREEN_DOCUMENT'],     documentUrls: [offscreenUrl]   });    if (existingContexts.length > 0) {     return;   }    // create offscreen document   if (creating) {     await creating;   } else {     creating = chrome.offscreen.createDocument({       url: path,       reasons: ['CLIPBOARD'],       justification: 'reason for needing the document',     });     await creating;     creating = null;   } } 

在向屏幕外文档发送消息之前,请调用 setupOffscreenDocument() 以确保该文档存在,如以下示例所示。

chrome.action.onClicked.addListener(async () => {   await setupOffscreenDocument('off_screen.html');    // Send message to offscreen document   chrome.runtime.sendMessage({     type: '...',     target: 'offscreen',     data: '...'   }); }); 

如需查看完整示例,请参阅 GitHub 上的 offscreen-clipboardoffscreen-dom 演示。

在 Chrome 116 之前:检查屏幕外文档是否已打开

runtime.getContexts() 已在 Chrome 116 中添加。在旧版 Chrome 中,使用 clients.matchAll() 检查是否存在屏幕外文档:

async function hasOffscreenDocument() {   if ('getContexts' in chrome.runtime) {     const contexts = await chrome.runtime.getContexts({       contextTypes: ['OFFSCREEN_DOCUMENT'],       documentUrls: [OFFSCREEN_DOCUMENT_PATH]     });     return Boolean(contexts.length);   } else {     const matchedClients = await clients.matchAll();     return matchedClients.some(client => {       return client.url.includes(chrome.runtime.id);     });   } } 

类型

CreateParameters

属性

  • 理由

    字符串

    开发者提供的字符串,用于更详细地说明需要背景信息的原因。用户代理 _可以_在向用户显示时使用此属性。

  • 个原因

    扩展程序创建屏幕外文档的原因。

  • 网址

    字符串

    要在文档中加载的(相对)网址。

Reason

枚举

“测试”
仅用于测试目的的原因。

“AUDIO_PLAYBACK”
指定离屏文档负责播放音频。

"IFRAME_SCRIPTING"
指定离屏文档需要嵌入 iframe 并通过脚本修改 iframe 的内容。

“DOM_SCRAPING”
指定离屏文档需要嵌入 iframe 并抓取其 DOM 以提取信息。

“BLOBS”
指定离屏文档需要与 Blob 对象(包括 URL.createObjectURL())互动。

“DOM_PARSER”
指定离屏文档需要使用 DOMParser API

“USER_MEDIA”
指定离屏文档需要与来自用户媒体(例如 getUserMedia())的媒体流进行交互。

“DISPLAY_MEDIA”
指定离屏文档需要与来自展示媒体(例如 getDisplayMedia())的媒体流进行互动。

“WEB_RTC”
指定了离屏文档需要使用 WebRTC API

“CLIPBOARD”
指定屏幕外文档需要与 Clipboard API 互动。

"LOCAL_STORAGE"
指定屏幕外文档需要访问 localStorage

“WORKERS”
指定了离屏文档需要衍生工作器。

“BATTERY_STATUS”
指定了离屏文档需要使用 navigator.getBattery

“MATCH_MEDIA”
指定离屏文档需要使用 window.matchMedia

“GEOLOCATION”
指定离屏文档需要使用 navigator.geolocation

方法

closeDocument()

chrome.offscreen.closeDocument(): Promise<void>

关闭扩展程序当前打开的屏幕外文档。

返回

  • Promise<void>

createDocument()

chrome.offscreen.createDocument(
  parameters: CreateParameters,
)
: Promise<void>

为扩展程序创建新的屏幕外文档。

参数

返回

  • Promise<void>