scripting.executeScript()

将脚本注入到目标上下文中。默认情况下,脚本在 document_idle 时运行。

注意:此方法在 Chrome 的 Manifest V3 或更高版本以及 Firefox 101 中可用。在 Safari 和 Firefox 102+ 中,此方法在 Manifest V2 中也可用。

要使用此 API,您必须拥有 "scripting" 权限以及目标 URL 的权限,无论是显式地作为 host 权限还是使用 activeTab 权限。请注意,某些特殊页面不允许使用此权限,包括阅读视图、view-source 和 PDF 查看器页面。

在 Firefox 和 Safari 中,部分 host 权限缺失可能导致执行成功(并解析 promise 得到部分结果)。在 Chrome 中,任何缺失的权限都会阻止任何执行发生(请参阅 Issue 1325114)。

您注入的脚本称为 内容脚本

这是一个异步函数,返回一个 Promise

语法

js
let results = await browser.scripting.executeScript(
  details             // object
)

参数

details

一个描述要注入脚本的对象。它包含以下属性

args 可选

要传递给函数的参数数组。仅当指定了 func 参数时才有效。参数必须是 JSON 可序列化的。

files 可选

string 数组。要注入的 JS 文件路径数组,相对于扩展的根目录。必须指定 filesfunc 中的一个。

func 可选

function。要注入的 JavaScript 函数。此函数会被序列化然后反序列化以进行注入。这意味着任何绑定的参数和执行上下文都会丢失。必须指定 filesfunc 中的一个。

injectImmediately 可选

boolean。是否尽快触发到目标的注入,但不一定是在页面加载之前。

目标

scripting.InjectionTarget。指定要注入脚本的目标的详细信息。

world 可选

scripting.ExecutionWorld。脚本执行的环境。

返回值

一个 Promise,它会解析为一个 InjectionResult 对象数组,这些对象代表了在每个注入的帧中注入脚本的结果。

如果注入失败(例如,注入目标无效),则 Promise 会被拒绝。当脚本执行开始后,无论成功(作为 result)还是失败(作为 error),其结果都会包含在结果中。

每个 InjectionResult 对象都具有以下属性

frameId

number。与注入关联的帧 ID。

result 可选

any。脚本执行的结果。

error 可选

any。如果发生错误,则包含脚本抛出或拒绝的值。通常这是一个带有 message 属性的错误对象,但它也可以是任何值(包括原始类型和 undefined)。

Chrome 尚不支持 error 属性(请参阅 Issue 1271527: Propagate errors from scripting.executeScript to InjectionResult)。作为替代,可以通过将要执行的代码包装在 try-catch 语句中来捕获运行时错误。未捕获的错误也会报告到目标标签页的控制台中。

脚本的结果是最后评估的语句,这类似于在 Web Console 中执行脚本时看到的结果(而不是任何 console.log() 输出)。例如,考虑以下脚本

js
let foo = "my result";
foo;

这里,结果数组包含字符串 "my result" 作为一个元素。

在 Firefox 中,脚本结果必须是 结构化克隆able 值,而在 Chrome 中,则必须是 JSON 可序列化 值。 Chrome 不兼容性 文章在 数据克隆算法 部分更详细地讨论了这种差异。

示例

此示例在活动标签页中执行了一行代码片段

js
browser.action.onClicked.addListener(async (tab) => {
  try {
    await browser.scripting.executeScript({
      target: {
        tabId: tab.id,
      },
      func: () => {
        document.body.style.border = "5px solid green";
      },
    });
  } catch (err) {
    console.error(`failed to execute script: ${err}`);
  }
});

此示例执行一个来自扩展打包的名为 "content-script.js" 的脚本。该脚本将在活动标签页中执行。该脚本将在子帧和主文档中执行

js
browser.action.onClicked.addListener(async (tab) => {
  try {
    await browser.scripting.executeScript({
      target: {
        tabId: tab.id,
        allFrames: true,
      },
      files: ["content-script.js"],
    });
  } catch (err) {
    console.error(`failed to execute script: ${err}`);
  }
});

浏览器兼容性

注意:此 API 基于 Chromium 的 chrome.scripting API。