scripting.executeScript()
将脚本注入目标上下文。默认情况下脚本将在 document_idle
时运行。
备注: 此方法在 Chrome 和 Firefox 101 的 Manifest V3 或更高版本中可用。在 Safari 和 Firefox 102+ 中,此方法也在 Manifest V2 中可用。
使用此 API 必须拥有 "scripting"
权限以及目标 URL 的权限,权限可以是明确的主机权限或使用 activeTab 权限。需要注意,部分特殊页面(包括阅读模式、查看源代码和 PDF 查看器页面)不支持该权限。
在 Firefox 和 Safari 中,缺少部分主机权限也会导致执行成功(这一部分的结果会包含在兑现的 Promise 中)。在 Chrome 中,缺少任意一个权限都会导致执行被阻止(参见 Issue 1325114)。
注入的脚本被称为内容脚本。
这是一个返回 Promise
的异步函数。
语法
let results = await browser.scripting.executeScript(
details // 对象
)
参数
details
-
描述注入脚本的对象,包含以下属性:
args
可选-
传递到函数中的参数数组,仅在指定了
func
参数时有效。参数必须是可 JSON 序列化的。 files
可选-
string
的array
。要注入的 JavaScript 文件相对于扩展的根目录的路径的数组。必须指定files
和func
其中之一。 func
可选-
function
。要注入的 JavaScript 函数。该函数将被序列化、反序列化以注入,因此任何绑定在函数上的参数和函数的执行上下文都将被丢失。必须指定files
和func
其中之一。 injectImmediately
可选-
boolean
。注入目标是否尽早触发注入(但不一定在页面加载之前)。 target
-
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.log()
输出)。例如,考虑这样的脚本:
let foo = "my result";
foo;
在该示例中,结果数组中将包含一个元素:字符串 "my result"
。
在 Firefox 中脚本的结果必须是一个可结构化克隆的值,而在 Chrome 中必须是一个可 JSON 序列化的值。Chrome 不兼容情况一文中的数据克隆算法部分更详细地讨论了这种差异。
示例
以下示例在活动标签页中执行一行代码:
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(`无法执行脚本:${err}`);
}
});
以下示例执行一个名为 "content-script.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(`无法执行脚本:${err}`);
}
});
浏览器兼容性
Report problems with this compatibility data on GitHubdesktop | mobile | ||||||
---|---|---|---|---|---|---|---|
executeScript | |||||||
InjectionResult | |||||||
InjectionResult.error | |||||||
InjectionResult.frameId | |||||||
InjectionResult.result | |||||||
injectImmediately | |||||||
world | |||||||
world.ISOLATED | |||||||
world.MAIN |
Legend
Tip: you can click/tap on a cell for more information.
- Full support
- Full support
- No support
- No support
- See implementation notes.
备注:
该 API 基于 Chromium 的 chrome.scripting
API。