如何使用清单 v3 在 chrome 扩展中执行定期后台工作

dep*_*her 3 manifest google-chrome-extension service-worker

background.js 机制在清单 v3 中被删除,我正在寻找如何在后台执行周期性操作,因为它已经消失了。

此升级指南说使用 chrome 警报 api: https://developer.chrome.com/docs/extensions/mv3/migration_to_service_workers/

具体来说,它说:

相反,我们可以使用 Alarms API。与其他侦听器一样,警报侦听器应在脚本的顶层注册。

目前尚不清楚它需要成为哪个脚本的顶层,但是当使用我的 chrome 扩展的入口点“popup.js”时,它会定期执行,但仅当 chrome 弹出窗口实际打开时才执行。即使弹出窗口关闭,我也需要它在后台执行。附带说明的是,我对 chrome.alarms 未定义,直到我将“警报”添加到清单文件中的权限,然后它不会阻塞,但我仍然遇到它不运行后台的问题。

由于上面的文章是在 Service Worker 的上下文中,我假设您需要将警报侦听器放在 service-worker.js 文件的顶层。只是这个不行。我在这里未定义 chrome.alarms (即使授予了“警报”权限):

service-worker.js

console.log("inside service worker")

// getting chrome.alarms undefined here
chrome.alarms.create("alarm", { periodInMinutes: 1 });
Run Code Online (Sandbox Code Playgroud)

将其放入安装事件侦听器中也没有帮助:

self.addEventListener('install', event => {
    console.log("Installing service worker")
    // still getting chrome.alarms undefined here
    chrome.alarms.create("alarm", { periodInMinutes: 1 });
    chrome.alarms.onAlarm.addListener((alarm) => {
        if (alarm.name === "alarm") {
            let milliseconds = new Date().getTime();
            console.log(milliseconds)
            chrome.action.setTitle({
                title: "Hello "+ milliseconds
            });
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

出于绝望,我也将“后台”权限添加到清单中,但这也没有帮助。

有什么线索如何在清单 v3 中定期在后台运行某些内容吗?看起来警报 api 应该是你这样做的,但显然服务工作者无法访问它?

wOx*_*xOm 10

迁移指南非常令人困惑,因为它是由 Web 开发人员编写的。它没有说的是,使用扩展的 Service Worker 与 ManifestV2 事件页面 99% 相同,减去在 Worker 中不可用的 DOM 相关 API。因此,您需要进行的更改本质上与切换到ManifestV2 中的事件页面相同。

由于上面的文章是在 Service Worker 的背景下进行的

background它与您在manifest.json 部分中声明的后台服务工作线程脚本相同。

警报监听器应该在脚本的顶层注册。

除了创建警报之外,您还需要添加一个侦听器,当后台脚本中触发警报事件时将调用该侦听器。“顶层”旨在简化“每次后台脚本唤醒时执行时,事件侦听器应该在事件循环的第一个任务中注册”。所以你可以把它放在任何你想要的地方,例如在其他函数中,甚至在同一个第一个任务中解析的 Promise 中。有关详细信息,请参阅JavaScript 事件循环

浏览器会记住警报,因此如果您需要定期警报,则应在安装扩展程序时仅创建一次。目前,每次 Service Worker 醒来时,您都会重新创建警报,从而重置其计时。幸好您指定了 id 参数,否则每次都会添加一个新警报。

此处未定义 chrome.alarms

要使用大部分chromeAPI,您需要将其名称添加到permissionsmanifest.json 中。chrome://extensions请注意,编辑清单或后台脚本后,您需要点击页面中扩展卡上的重新加载按钮。

  • 清单.json:

    "manifest_version": 3,
    "background": { "service_worker": "bg.js" },
    "permissions": [ "alarms" ],
    
    Run Code Online (Sandbox Code Playgroud)
  • 背景.js:

    chrome.alarms.onAlarm.addListener(a => {
      console.log('Alarm! Alarm!', a);
    });
    
    chrome.runtime.onInstalled.addListener(() => {
      chrome.alarms.get('alarm', a => {
        if (!a) {
          chrome.alarms.create('alarm', {periodInMinutes: 1});
        }
      });
    });
    
    Run Code Online (Sandbox Code Playgroud)

self.addEventListener('install',不是必需的,因为扩展的 Service Worker 是在安装扩展时在内部注册的。MV3 不需要任何 Service Worker 生命周期事件,并且大多数/全部甚至无法工作。