devtools.inspectedWindow.eval()
在开发工具连接的窗口中执行 JavaScript。
这在某种程度上类似于使用 tabs.executeScript() 来附加内容脚本,但有两个主要区别:
首先,JavaScript 可以使用一组 浏览器通常在其开发者工具控制台实现中提供的特殊命令:例如,使用“$0”来引用“检查器”中当前选中的元素。
其次,您执行的 JavaScript 可以看到页面加载的脚本对页面所做的任何更改。这与内容脚本相反,内容脚本看到页面 就像在没有加载任何页面脚本的情况下存在的那样。但是,请注意,内容脚本提供的隔离是一项故意的安全功能,旨在让恶意或不合作的网页更难通过重新定义 DOM 函数和属性来混淆或破坏 WebExtensions API。这意味着如果您通过使用 eval() 来放弃此保护,您需要非常小心,并且除非您需要使用 eval(),否则应使用内容脚本。
脚本默认在页面的主框架中进行评估。脚本必须评估为可以表示为 JSON 的值(这意味着,例如,它可能无法评估为函数或包含任何函数的对象)。默认情况下,脚本看不到附加到页面的任何内容脚本。
您不能在特权浏览器窗口(例如“about:addons”)上调用 eval()。
您可以选择提供一个 options 参数,其中包括在不同框架或已附加内容脚本的上下文中评估脚本的选项。请注意,Firefox 尚不支持 options 参数。
eval() 函数返回一个 Promise,该 Promise 解析为脚本的评估结果或错误。
辅助函数
脚本可以访问许多对象,这些对象有助于注入的脚本与开发者工具进行交互。目前支持以下辅助函数:
语法
let evaluating = browser.devtools.inspectedWindow.eval(
expression, // string
options // object
)
参数
表达式-
string。要评估的 JavaScript 表达式。该字符串必须评估为可表示为 JSON 的对象,否则将抛出异常。例如,expression不能评估为函数。 options可选-
object。函数的选项(请注意,Firefox 尚不支持此选项),如下所示:frameURL可选-
string。要评估表达式的框架的 URL。如果省略此参数,则在窗口的主框架中评估表达式。 useContentScriptContext可选-
boolean。如果为true,则在扩展程序已附加到页面的任何内容脚本的上下文中评估表达式。如果设置此选项,则您必须确实已将某些内容脚本附加到页面,否则将抛出开发者工具错误。 contextSecurityOrigin可选-
string。在由不同扩展程序附加的内容脚本的上下文中评估表达式,其源与此处给出的值匹配。这会覆盖useContentScriptContext。
返回值
一个 Promise,它将使用一个包含两个元素的 array 来兑现。
如果没有发生错误,则第一个元素将包含评估表达式的结果,第二个元素将是 undefined。
如果发生错误,第一个元素将是 undefined,第二个元素将包含一个提供错误详细信息的对象。区分两种不同类型的错误:
-
评估 JavaScript 时遇到的错误(例如,表达式中的语法错误)。在这种情况下,第二个元素将包含:
- 一个布尔属性
isException,设置为true - 一个字符串属性
value,提供更多详细信息。
- 一个布尔属性
-
其他错误(例如,表达式评估为无法表示为 JSON 的对象)。在这种情况下,第二个元素将包含:
- 一个布尔属性
isError,设置为true - 一个字符串属性
code,包含错误代码。
- 一个布尔属性
示例
这会测试 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 辅助函数来设置“检查器”中当前选定元素的背景颜色。
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。