devtools.inspectedWindow.eval()
在 devtools 附加到的窗口中执行 JavaScript。
这有点像使用 tabs.executeScript()
附加内容脚本,但有两个主要区别
首先,JavaScript 可以使用一组 浏览器通常在其 devtools 控制台实现中提供的特殊命令:例如,使用“$0”引用 Inspector 中当前选定的元素。
其次,您执行的 JavaScript 可以看到页面加载的脚本对页面所做的任何更改。这与内容脚本形成对比,内容脚本会 查看页面在没有加载页面脚本的情况下会如何存在。但是,请注意,内容脚本提供的隔离是一项有意的安全功能,旨在使恶意或不合作的网页更难以通过重新定义 DOM 函数和属性来混淆或破坏 WebExtensions API。这意味着如果您通过使用 eval()
放弃此保护,则需要非常小心,并且应使用内容脚本,除非您需要使用 eval()
。
默认情况下,脚本在页面的主框架中进行评估。脚本必须评估为可以表示为 JSON 的值(这意味着,例如,它可能不会评估为函数或包含任何函数的对象)。默认情况下,脚本不会看到附加到页面的任何内容脚本。
您不能对特权浏览器窗口(例如“about:addons”)调用 eval()
。
您可以选择提供 options
参数,其中包括在不同框架或附加内容脚本的上下文中评估脚本的选项。请注意,Firefox 尚未支持 options
参数。
eval()
函数返回一个 Promise
,该函数解析为脚本的评估结果或错误。
帮助器
语法
let evaluating = browser.devtools.inspectedWindow.eval(
expression, // string
options // object
)
参数
expression
-
string
。要评估的 JavaScript 表达式。字符串必须评估为可以表示为 JSON 的对象,否则会抛出异常。例如,expression
不能评估为函数。 options
可选-
object
。函数的选项(请注意,Firefox 尚未支持此选项),如下所示frameURL
可选-
string
。要评估表达式的框架的 URL。如果省略此项,则在窗口的主框架中评估表达式。 useContentScriptContext
可选-
boolean
。如果为true
,则在与此扩展附加到页面的任何内容脚本的上下文中评估表达式。如果设置此选项,则必须实际将某些内容脚本附加到页面,否则会抛出 Devtools 错误。 contextSecurityOrigin
可选-
string
。在由不同扩展附加的内容脚本的上下文中评估表达式,其来源与此处给定的值匹配。这会覆盖useContentScriptContext
。
返回值
一个 Promise
,它将使用包含两个元素的 array
填充。
如果未发生错误,则元素 0 将包含评估表达式的结果,元素 1 将为 undefined
。
如果发生错误,则元素 0 将为 undefined
,元素 1 将包含一个对象,其中提供有关错误的详细信息。区分两种不同的错误
- 评估 JavaScript 时遇到的错误(例如,表达式中的语法错误)。在这种情况下,元素 1 将包含
- 一个布尔属性
isException
,设置为true
- 一个字符串属性
value
,提供更多详细信息。
- 一个布尔属性
- 其他错误(例如,评估结果为无法表示为 JSON 的对象的表达式)。在这种情况下,元素 1 将包含
- 一个布尔属性
isError
,设置为true
- 一个字符串属性
code
,包含错误代码。
- 一个布尔属性
浏览器兼容性
BCD 表仅在启用 JavaScript 的浏览器中加载。
示例
这测试 jQuery 是否在被检查的窗口中定义,并记录结果。请注意,这在内容脚本中不起作用,因为即使定义了 jQuery,内容脚本也不会看到它。
function handleError(error) {
if (error.isError) {
console.log(`Devtools error: ${error.code}`);
} else {
console.log(`JavaScript error: ${error.value}`);
}
}
function handleResult(result) {
console.log(result);
if (result[0] !== undefined) {
console.log(`jQuery: ${result[0]}`);
} else if (result[1]) {
handleError(result[1]);
}
}
const checkjQuery = "typeof jQuery !== 'undefined'";
evalButton.addEventListener("click", () => {
browser.devtools.inspectedWindow.eval(checkjQuery).then(handleResult);
});
帮助器示例
这使用 $0
帮助器设置 Inspector 中当前选定的元素的背景颜色
const evalButton = document.querySelector("#reddinate");
const evalString = "$0.style.backgroundColor = 'red'";
function handleError(error) {
if (error.isError) {
console.log(`Devtools error: ${error.code}`);
} else {
console.log(`JavaScript error: ${error.value}`);
}
}
function handleResult(result) {
if (result[1]) {
handleError(result[1]);
}
}
evalButton.addEventListener("click", () => {
browser.devtools.inspectedWindow.eval(evalString).then(handleResult);
});
这使用 inspect()
帮助器选择页面中的第一个 <h1> 元素
const inspectButton = document.querySelector("#inspect");
const inspectString = "inspect(document.querySelector('h1'))";
function handleError(error) {
if (error.isError) {
console.log(`Devtools error: ${error.code}`);
} else {
console.log(`JavaScript error: ${error.value}`);
}
}
function handleResult(result) {
if (result[1]) {
handleError(result[1]);
}
}
inspectButton.addEventListener("click", () => {
browser.devtools.inspectedWindow.eval(inspectString).then(handleResult);
});
注意:此 API 基于 Chromium 的 chrome.devtools
API。