什么是 Chrome 脚本 API?

569 阅读4分钟

Chrome Scripting API 和 Manifest V3 简介

img

Chrome Scripting API是引入到 Chrome 浏览器扩展平台的最新功能之一。它是 Manifest V3 更新的一部分,让用户能够在Chrome中将JavaScript 和 CSS 注入网页。

在本文中,我将讨论Chrome Scripting API 的一些核心功能,让您更好地了解它。

什么是 Chrome 脚本 API?

Chrome Scripting 是 Manifest V3 中添加的一个新命名空间。

它取代了 Manifest V2 的 Tab API 方法,可以将脚本和样式注入网页。例如,chrome.tabs.executeScriptchrome.tabs.insertCSS方法已经由Tab API移到了与MV3更新中的Chrome的Chrome Scripting API。

为脚本引入新命名空间的原因是什么?

正如我所提到的,大多数脚本功能已经是 Tab API 的一部分。那么,为什么 Chrome 会为脚本引入一个新的命名空间?

这个决定背后有几个原因,我在下面列出了三个主要原因:

1. 降低Tab API的功能复杂度

近年来,选项卡 API 被各种功能重载,如选项卡管理、选择管理、窗口组织和导航。此外,其中一些功能需要权限处理,开发人员经常将它们与脚本功能混淆。

为了解决这个问题,引入了Scripting API,将所有的脚本功能冲Tab API中移除。

Scripting API 的引入通过从 Tab API 中移除所有脚本功能来解决这个问题。

2. Script API 中存在安全漏洞

对于 executeScript API,它允许扩展程序在目标选项卡中执行任意脚本代码的能力。这种行为心怀恶意的开发人员打开了从远程服务器获取任意脚本并在任何页面内运行它的大门。

3. 带来更多的脚本功能

Manifest V3 更新的一个主要目的是为 Chrome 扩展平台带来更多脚本功能。与 Manifest V2 相比,它增加了动态内容脚本、特定于目标的frame和目标非选项卡上下文等功能。

我想你现在明白了什么是Scripting API以及它为什么被引入。那么接下来让我们看看 Scripting API 和 Tab API 之间的主要区别是什么。

Chrome 脚本 API 与选项卡 API

尽管引入了 Scripting API 是为了从Tab API 移出功能,但是同时对几个主要的功能进行了该进 。因此,我将从chrome.tabs.executeScriptchrome.scripting.executeScript函数中提取一些示例用法,并为您突出显示改进前后的差异。

1. 允许使用单个 API 调用定位多个frame

在 Manifest V2 中,开发人员只能定位到一个选项卡或单个特定选项卡中的所有frame。例如,下面的代码展示了我们如何一次获取所有frame并在它们上一一执行脚本。

// Manifest V2

chrome.browserAction.onClicked.addListener((tab) => {
  chrome.webNavigation.getAllFrames({tabId: tab.id}, (frames) => {
    let frame1 = frames[0].frameId;
    let frame2 = frames[1].frameId;

    chrome.tabs.executeScript(tab.id, {
      frameId: frame1,
      file: 'content-script.js',
    });
    
    chrome.tabs.executeScript(tab.id, {
      frameId: frame2,
      file: 'content-script.js',
    });
  });
})

但是,Manifest V3 更新后,我们可以一次在多个选定的frame上执行脚本。

Manifest V3 更新已将frameIdTab API的属性替换为一个名为的新属性,该属性frameIds同时接受多个frame ID。所以,如果我们再次考虑上面的例子,现在我们可以一次选择两个frame执行脚本。

// Manifest V3

chrome.action.onClicked.addListener(async (tab) => {
  let frames = await chrome.webNavigation.getAllFrames({tabId: tab.id});
  let frame1 = frames[0].frameId;
  let frame2 = frames[1].frameId;

  chrome.scripting.executeScript({
    target: {
      tabId: tab.id,
      frameIds: [frame1, frame2],
    },
    files: ['content-script.js'],
  });});

**注意:**此外,您可以一次执行多个脚本,因为 files 属性接受脚本作为数组。

2. 允许扩展将函数作为内容脚本注入

在 Manifest V2 中,将脚本注入网页的唯一方法是构建动态代码。

例如,如果您想在用户单击操作按钮时运行脚本,则需要获取脚本文件,构建如下动态代码,然后执行它。

// Manifest V2

chrome.browserAction.onClicked.addListener(async (tab) => {
  let response = await fetch('../script.js');
  let userScript = await response.text();

  chrome.tabs.executeScript({
    code: userScript,
  });
});

Manifest V3 改进了这个过程,现在我们可以直接将函数和参数传递给executeScripts函数。例如,我们可以使用 Manifest V3 编写相同的函数,并使用funcargs属性传递函数名和参数。

// Manifest V3

function welcometUser(name) {
  alert(`Welcome, ${name}!`);
}

chrome.action.onClicked.addListener(async (tab) => {
  let response = await fetch('../script.js');  
  let user = await response.json();
  let name= user.name|| '<NAME>';

  chrome.scripting.executeScript({
    target: {tabId: tab.id},
    func: welcometUser,
    args: [name],
  });
});

3. 返回脚本注入结果的改进

我们可以注意到的另一个主要改进是返回脚本注入结果的方法。如果我们考虑executeScriptManifest V2的函数,它将返回一个简单的执行结果数组。

在 Manifest V3 中,函数能够返回对象数组

此外,这些结果对象指示每个结果的frame ID,使开发人员更容易根据它们采取行动。

// Manifest V3

chrome.action.onClicked.addListener(async (tab) => {
  let results = await chrome.scripting.executeScript({
    target: {tabId: tab.id, allFrames: true},
    files: ['script.js'],
  }); 
  
  // results == [
  //   {frameId: 0, result: x},
  //   {frameId: 1235, result: y},
  //   {frameId: 1234, result: z}
  // ]

结论

在本文中,我介绍了 Chrome scripting API 以及引入单独的脚本 API 背后的原因。

尽管大多数功能类似于 Manifest V2 中的 Tab API,但 Manifest V3 更新中有几个令人兴奋的改进。

因此,我鼓励您熟悉这些以提高您的 Chrome 扩展程序开发技能。

感谢阅读!!!