如何在Manifest V3中用Web扩展注入一个全局

356 阅读2分钟

对于那些不熟悉网络扩展开发世界的人来说,一场风暴正在Chrome浏览器上酝酿。谷歌将停止对manifest第二版的支持,绝大多数网络扩展都是使用这个版本。第三版清单有许多变化,但最大的变化是从持久的后台脚本转移到服务工作者。这......是......巨大的......变化。

从清单第2版到第3版的变化包括:

  • 从持久的后台脚本到5分钟后可能死亡的服务工作者
  • 不使用<iframe> 元素或服务工作者的其他 DOM API
  • 所有API都变成了基于承诺的
  • 从CSP的角度看对内容的限制

网络扩展经常使用的一个功能是在每次新的页面加载时执行脚本。 对于MetaMask这样的网络扩展,我们需要提供一个全局window.ethereum ,供dApps使用。 那么,我们如何用manifest第3版做到这一点呢?

从Chrome v102开始,开发者可以为内容脚本定义一个world 属性,其值为isolatedmain (在页面中)。虽然开发人员应在扩展的manifest.json 文件中定义content_scripts ,但main 的值只有在您从服务工作者那里以编程方式定义时才能真正发挥作用(由于 Chrome 的一个错误):

await chrome.scripting.registerContentScripts([
  {
    id: 'inpage',
    matches: ['http://*/*', 'https://*/*'],
    js: ['in-page.js'],
    runAt: 'document_start',
    world: 'MAIN',
  },
]);

在上面的例子中,每次加载新页面时,in-page.js 都会被注入并在主内容标签中执行。这个in-page.js 文件设置了window.ethereum ,供所有dApps使用。如果worldundefinedisolated ,该脚本仍会执行,但会在一个隔离的环境中执行。

Manifest第3版的工作是相当艰巨的,所以请拥抱你最接近的扩展开发者。 有许多巨大的结构性变化,浏览这些变化是一个残酷的推动力!