CHROME扩展开发之·离屏接口chrome.offscreen

接口简介

chrome.offscreen 是chrome 109以上开始提供的离屏 API 创建和管理离屏文档。使用该api需要在manifest中的Permissions声明 “offscreen”,该api可以实现不打开浏览器标签的情况下操作dom,实现mv3后台无法操作dom以及生命周期问题。
服务工作者没有DOM访问权限,许多网站都有限制内容脚本功能的内容安全策略。Offscreen API允许扩展在隐藏文档中使用DOM API,而不会通过打开新窗口或选项卡来中断用户体验。 runtime API是屏幕外文档支持的唯一扩展API。

清单

要使用Offscreen API,请在扩展清单中声明 “offscreen” 权限。举例来说:

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

用法

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

以下是屏幕外文档与正常页面行为不同的其他方式:

  • 屏幕外文档的URL必须是绑定有扩展名的静态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',
});

参数原因(reasons)

有关有效原因的列表,请参阅原因部分。在文档创建期间设置原因以确定文档的寿命。 AUDIO_PLAYBACK 原因将文档设置为在30秒后关闭而不播放音频。所有其他的原因都没有设定寿命限制。

  • “TESTING” 仅用于测试目的的原因。
  • “AUDIO_PLAYBACK” 指定屏幕外文档负责播放音频。
  • “IFRAME_SCRIPTING” 指定屏幕外文档需要嵌入iframe并为其编写脚本,以便修改iframe的内容。
  • “DOM_SCRAPING” 指定屏幕外文档需要嵌入iframe并抓取其DOM以提取信息。
  • “BLOBS” 指定屏幕外文档需要与Blob对象(包括 URL.createObjectURL() )交互。
  • “DOM_PARSER” 指定屏幕外文档需要使用
  • “USER_MEDIA” 指定屏幕外文档需要与来自用户媒体(例如 getUserMedia() )的媒体流进行交互。
  • “DISPLAY_MEDIA” 指定屏幕外文档需要与显示媒体(例如 getDisplayMedia() )中的媒体流交互。
  • “WEB_RTC” 指定屏幕外文档需要使用Web实时通信功能
  • “CLIPBOARD” 指定离屏文档需要与之交互剪切板
  • “LOCAL_STORAGE” 指定屏幕外文档需要访问localStorage
  • “WORKERS” 指定屏幕外文档需要派生工作进程。
  • “BATTERY_STATUS” 指定屏幕外文档需要使用navigator.getBattery。
  • “MATCH_MEDIA” 指定屏幕外文档需要使用window.matchMedia。
  • “GEOLOCATION” 指定屏幕外文档需要使用navigator.geolocation。

案例Examples

下面的示例说明如何确保存在屏幕外文档。 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 await matchedClients.some(client => {
        client.url.includes(chrome.runtime.id);
    });
  }
}

创建离屏页面 chrome.offscreen.createDocument

chrome.offscreen.createDocument({
	url: chrome.runtime.getURL('offscreen/index.html'), // 你的离屏页面地址
	reasons: ['DOM_PARSER'], // 扩展创建屏幕外文档的原因该接口需要实现什么参数参考上面 “参数原因(reasons)” 未正确声明会导致页面报错获取不到对应的权限,如未声明DOM_PARSER 则页面就获取不到document
	justification: "使用的理由", // 开发人员提供的字符串,更详细地解释了背景上下文的必要性。用户代理可以在向用户显示时使用此。
})

closeDocument 关闭文档

chrome.offscreen.closeDocument(
  callback?: function,
)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值