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。