devtools.inspectedWindow.eval()

在開發工具連線的視窗中執行 JavaScript。

這在某種程度上類似於使用 tabs.executeScript() 來附加內容指令碼,但有兩個主要區別:

首先,JavaScript 可以使用一組 瀏覽器通常在其開發者工具控制檯實現中提供的特殊命令:例如,使用“$0”來引用“檢查器”中當前選中的元素。

其次,您執行的 JavaScript 可以看到頁面載入的指令碼對頁面所做的任何更改。這與內容指令碼相反,內容指令碼看到頁面 就像在沒有載入任何頁面指令碼的情況下存在的那樣。但是,請注意,內容指令碼提供的隔離是一項故意的安全功能,旨在讓惡意或不合作的網頁更難透過重新定義 DOM 函式和屬性來混淆或破壞 WebExtensions API。這意味著如果您透過使用 eval() 來放棄此保護,您需要非常小心,並且除非您需要使用 eval(),否則應使用內容指令碼。

指令碼預設在頁面的主框架中進行評估。指令碼必須評估為可以表示為 JSON 的值(這意味著,例如,它可能無法評估為函式或包含任何函式的物件)。預設情況下,指令碼看不到附加到頁面的任何內容指令碼。

您不能在特權瀏覽器視窗(例如“about:addons”)上呼叫 eval()

您可以選擇提供一個 options 引數,其中包括在不同框架或已附加內容指令碼的上下文中評估指令碼的選項。請注意,Firefox 尚不支援 options 引數。

eval() 函式返回一個 Promise,該 Promise 解析為指令碼的評估結果或錯誤。

輔助函式

指令碼可以訪問許多物件,這些物件有助於注入的指令碼與開發者工具進行互動。目前支援以下輔助函式:

$0

包含對“開發者工具檢查器”中當前選定元素的引用。

inspect()

給定一個物件,如果它是頁面中的 DOM 元素,則在“開發者工具檢查器”中選中它;否則,它會在控制檯中建立一個物件預覽。

檢視一些示例。

語法

js
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 已定義,內容指令碼也看不到它。

js
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 輔助函式來設定“檢查器”中當前選定元素的背景顏色。

js
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> 元素。

js
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。