chrome.scripting

說明

使用 chrome.scripting API 在不同情況下執行指令碼。

權限

scripting

適用國家/地區

Chrome 88 以上版本 MV3 以上版本

資訊清單

如要使用 chrome.scripting API,請在資訊清單中宣告 "scripting" 權限,以及要插入指令碼的頁面主機權限。使用 "host_permissions" 鍵或 "activeTab" 權限,可以授予臨時主機權限。以下範例使用 ActiveTab 權限。

{
  "name": "Scripting Extension",
  "manifest_version": 3,
  "permissions": ["scripting", "activeTab"],
  ...
}

概念和用法

您可以使用 chrome.scripting API,將 JavaScript 和 CSS 插入網站。這與您對內容指令碼所能進行的操作類似。不過,如果使用 chrome.scripting 命名空間,擴充功能可以在執行階段做出決定。

插入目標

您可以使用 target 參數指定要插入 JavaScript 或 CSS 的目標。

tabId 是唯一的必填欄位。根據預設,插入作業會在指定分頁的主要頁框中執行。

function getTabId() { ... }

chrome.scripting
    .executeScript({
      target : {tabId : getTabId()},
      files : [ "script.js" ],
    })
    .then(() => console.log("script injected"));

如要在指定分頁的所有頁框中執行,您可以將 allFrames 布林值設為 true

function getTabId() { ... }

chrome.scripting
    .executeScript({
      target : {tabId : getTabId(), allFrames : true},
      files : [ "script.js" ],
    })
    .then(() => console.log("script injected in all frames"));

您也可以指定個別的影格 ID,插入分頁的特定影格。如要進一步瞭解影格 ID,請參閱 chrome.webNavigation API

function getTabId() { ... }

chrome.scripting
    .executeScript({
      target : {tabId : getTabId(), frameIds : [ frameId1, frameId2 ]},
      files : [ "script.js" ],
    })
    .then(() => console.log("script injected on target frames"));

已插入程式碼

擴充功能可透過外部檔案或執行階段變數指定要插入的程式碼。

Files

檔案必須指定為字串,這些字串是擴充功能根目錄的相對路徑。下列程式碼會將 script.js 檔案插入分頁的主要頁框。

function getTabId() { ... }

chrome.scripting
    .executeScript({
      target : {tabId : getTabId()},
      files : [ "script.js" ],
    })
    .then(() => console.log("injected script file"));

執行階段函式

使用 scripting.executeScript() 插入 JavaScript 時,可以指定要執行的函式,而非檔案。這個函式應為目前擴充功能結構定義可用的函式變數。

function getTabId() { ... }
function getTitle() { return document.title; }

chrome.scripting
    .executeScript({
      target : {tabId : getTabId()},
      func : getTitle,
    })
    .then(() => console.log("injected a function"));
function getTabId() { ... }
function getUserColor() { ... }

function changeBackgroundColor() {
  document.body.style.backgroundColor = getUserColor();
}

chrome.scripting
    .executeScript({
      target : {tabId : getTabId()},
      func : changeBackgroundColor,
    })
    .then(() => console.log("injected a function"));

您可以使用 args 屬性解決這個問題:

function getTabId() { ... }
function getUserColor() { ... }
function changeBackgroundColor(backgroundColor) {
  document.body.style.backgroundColor = backgroundColor;
}

chrome.scripting
    .executeScript({
      target : {tabId : getTabId()},
      func : changeBackgroundColor,
      args : [ getUserColor() ],
    })
    .then(() => console.log("injected a function"));

執行階段字串

如要在網頁中插入 CSS,您也可以指定在 css 屬性中使用的字串。這個選項僅適用於 scripting.insertCSS();您無法使用 scripting.executeScript() 執行字串。

function getTabId() { ... }
const css = "body { background-color: red; }";

chrome.scripting
    .insertCSS({
      target : {tabId : getTabId()},
      css : css,
    })
    .then(() => console.log("CSS injected"));

處理結果

執行 JavaScript 的結果會傳送至擴充功能。每個影格會包含一項結果。主影格保證是結果陣列中的第一個索引;所有其他影格的順序皆非確定性。

function getTabId() { ... }
function getTitle() { return document.title; }

chrome.scripting
    .executeScript({
      target : {tabId : getTabId(), allFrames : true},
      func : getTitle,
    })
    .then(injectionResults => {
      for (const {frameId, result} of injectionResults) {
        console.log(`Frame ${frameId} result:`, result);
      }
    });

scripting.insertCSS()」不會傳回任何結果。

Promise

如果指令碼執行產生的值代表承諾,Chrome 會等待承諾並傳回產生的值。

function getTabId() { ... }
async function addIframe() {
  const iframe = document.createElement("iframe");
  const loadComplete =
      new Promise(resolve => iframe.addEventListener("load", resolve));
  iframe.src = "https://example.com";
  document.body.appendChild(iframe);
  await loadComplete;
  return iframe.contentWindow.document.title;
}

chrome.scripting
    .executeScript({
      target : {tabId : getTabId(), allFrames : true},
      func : addIframe,
    })
    .then(injectionResults => {
      for (const frameResult of injectionResults) {
        const {frameId, result} = frameResult;
        console.log(`Frame ${frameId} result:`, result);
      }
    });

示例

取消註冊所有動態內容指令碼

下列程式碼片段包含的函式,可將擴充功能先前註冊的所有動態內容指令碼取消註冊。

async function unregisterAllDynamicContentScripts() {
  try {
    const scripts = await chrome.scripting.getRegisteredContentScripts();
    const scriptIds = scripts.map(script => script.id);
    return chrome.scripting.unregisterContentScripts(scriptIds);
  } catch (error) {
    const message = [
      "An unexpected error occurred while",
      "unregistering dynamic content scripts.",
    ].join(" ");
    throw new Error(message, {cause : error});
  }
}

如要試用 chrome.scripting API,請從 Chrome 擴充功能範例存放區安裝指令碼範例

類型

ContentScriptFilter

Chrome 96 以上版本

屬性

CSSInjection

屬性

  • css

    字串 選用

    字串,內含要插入的 CSS。必須明確指定為 filescss 其中之一。

  • 檔案

    string[] 選填

    要插入的 CSS 檔案路徑 (相對於擴充功能的根目錄)。必須明確指定為 filescss 其中之一。

  • 發跡地

    StyleOrigin (選用)

    插入的樣式來源。預設值為 'AUTHOR'

  • 詳細說明要插入 CSS 的目標。

ExecutionWorld

Chrome 95 以上版本

指令碼在 JavaScript 環境中執行的情況。

列舉

"ISOLATED"
指定隔離世界,這是這項擴充功能專屬的執行環境。

"MAIN"
指定 DOM 的主要世界,也就是與代管網頁的 JavaScript 共用的執行環境。

InjectionResult

屬性

  • documentId

    字串

    Chrome 106 以上版本

    與插入作業相關聯的文件。

  • frameId

    號碼

    Chrome 90 以上版本

    與插入作業相關聯的框架。

  • 結果

    任何選填

    指令碼執行的結果。

InjectionTarget

屬性

  • allFrames

    布林值 (選用)

    是否應將指令碼插入分頁中的所有頁框。預設值為 false。如果指定 frameIds,則不得為 true。

  • documentIds

    string[] 選填

    Chrome 106 以上版本

    要插入的特定 documentId ID。如果已設定 frameIds,就無法設定這個屬性。

  • frameIds

    number[] 選填

    要插入的特定影格 ID

  • tabId

    號碼

    要插入的分頁 ID。

RegisteredContentScript

Chrome 96 以上版本

屬性

  • allFrames

    布林值 (選用)

    如果指定 True,系統就會在所有頁框中插入畫面,即使該頁框並非分頁最頂端的頁框也一樣。每個頁框都會根據網址規定分別檢查;如果不符合網址規定,則不會插入子頁框。預設值為 False,表示只比對頂層頁框。

  • css

    string[] 選填

    要插入相符頁面的 CSS 檔案清單。這些引數會依照它們出現在此陣列中的順序插入,在頁面建構或顯示任何 DOM 之前。

  • excludeMatches

    string[] 選填

    排除會插入此內容指令碼的網頁。如要進一步瞭解這些字串的語法,請參閱比對模式

  • id

    字串

    API 呼叫中指定的內容指令碼 ID。不得以「_」開頭,因為這會做為產生的指令碼 ID 的前置字串。

  • js

    string[] 選填

    要插入相符網頁的 JavaScript 檔案清單。這些引數會依照出現在此陣列中的順序插入。

  • matchOriginAsFallback

    布林值 (選用)

    Chrome 119 以上版本

    指出指令碼是否能插入至網址含有不支援的配置的頁框中;具體而言:about:, data:、blob: 或 filesystem:。在這類情況下,系統會檢查網址的來源,以判斷是否應插入指令碼。如果來源是 null (例如「資料:網址」),則使用的起點會是建立目前頁框的頁框,或是啟動這個頁框的導覽頁框。請注意,這可能不是上層頁框。

  • 相符項目

    string[] 選填

    指定要將這個內容指令碼插入哪些網頁。如要進一步瞭解這些字串的語法,請參閱比對模式。必須為 registerContentScripts 指定。

  • persistAcrossSessions

    布林值 (選用)

    指定是否將此內容指令碼保留在日後的工作階段中。預設值為 true。

  • runAt

    RunAt 選用

    指定將 JavaScript 檔案插入網頁的時機。建議使用,預設值為 document_idle

  • 國際
    Chrome 102 以上版本

    要執行指令碼的 JavaScript「world」。預設值為 ISOLATED

ScriptInjection

屬性

  • args

    any[] 選填

    Chrome 92 以上版本

    要傳遞至指定函式的引數。只有在指定 func 參數時,這個值才有效。這些引數必須是 JSON 可序列化。

  • 檔案

    string[] 選填

    要插入的 JS 或 CSS 檔案路徑 (相對於擴充功能的根目錄)。必須明確指定為 filesfunc 其中之一。

  • injectImmediately

    布林值 (選用)

    Chrome 102 以上版本

    是否應盡快在目標中觸發插入功能。請注意,這不保證會在網頁載入前進行插入,因為在指令碼到達目標時,網頁可能已經載入。

  • 詳細說明指定要插入指令碼的目標。

  • 國際
    Chrome 95 以上版本

    要執行指令碼的 JavaScript「world」。預設值為 ISOLATED

  • func

    void optional

    Chrome 92 以上版本

    要插入的 JavaScript 函式。此函式將經過序列化,然後去序列化,以供插入。這表示所有繫結的參數和執行內容都會遺失。必須明確指定為 filesfunc 其中之一。

    func 函式如下所示:

    ()=> {...}

StyleOrigin

樣式變更的來源。詳情請參閱樣式來源

列舉

方法

executeScript()

Promise
chrome.scripting.executeScript(
  injection: ScriptInjection,
  callback?: function,
)

將指令碼插入目標結構定義。根據預設,指令碼會在 document_idle 執行,如果網頁已載入,則會立即執行。如果設定了 injectImmediately 屬性,即使網頁尚未載入完成,指令碼也會在沒有等待的情況下插入。如果指令碼評估結果為 promise,瀏覽器就會等待承諾期滿並傳回產生的值。

參數

傳回

  • Promise<InjectionResult[]>

    Chrome 90 以上版本

    Manifest V3 以上版本支援 Promise,但是為了提供回溯相容性而提供的回呼。您無法在同一個函式呼叫中同時使用這兩者。承諾會用傳遞至回呼的同類型解析。

getRegisteredContentScripts()

Promise Chrome 96 以上版本
chrome.scripting.getRegisteredContentScripts(
  filter?: ContentScriptFilter,
  callback?: function,
)

傳回這個擴充功能中所有符合指定篩選條件的動態註冊內容指令碼。

參數

傳回

  • Manifest V3 以上版本支援 Promise,但是為了提供回溯相容性而提供的回呼。您無法在同一個函式呼叫中同時使用這兩者。承諾會用傳遞至回呼的同類型解析。

insertCSS()

Promise
chrome.scripting.insertCSS(
  injection: CSSInjection,
  callback?: function,
)

將 CSS 樣式表插入目標結構定義。如果指定多個頁框,則系統會忽略失敗的插入作業。

參數

  • 注射避孕針

    要插入的樣式詳細資料。

  • 回呼

    函式選用

    callback 參數如下所示:

    ()=>void

傳回

  • Promise<void>

    Chrome 90 以上版本

    Manifest V3 以上版本支援 Promise,但是為了提供回溯相容性而提供的回呼。您無法在同一個函式呼叫中同時使用這兩者。承諾會用傳遞至回呼的同類型解析。

registerContentScripts()

Promise Chrome 96 以上版本
chrome.scripting.registerContentScripts(
  scripts: RegisteredContentScript[],
  callback?: function,
)

為這個擴充功能註冊一或多個內容指令碼。

參數

  • 包含要註冊的指令碼清單。如果剖析/檔案驗證期間發生錯誤,或是指定的 ID 已存在,系統就不會註冊任何指令碼。

  • 回呼

    函式選用

    callback 參數如下所示:

    ()=>void

傳回

  • Promise<void>

    Manifest V3 以上版本支援 Promise,但是為了提供回溯相容性而提供的回呼。您無法在同一個函式呼叫中同時使用這兩者。承諾會用傳遞至回呼的同類型解析。

removeCSS()

Promise Chrome 90 以上版本
chrome.scripting.removeCSS(
  injection: CSSInjection,
  callback?: function,
)

移除這個擴充功能先前從目標內容插入的 CSS 樣式表。

參數

  • 注射避孕針

    要移除的樣式詳細資料。請注意,cssfilesorigin 屬性必須與透過 insertCSS 插入的樣式表完全相符。嘗試移除不存在的樣式表是免人工管理。

  • 回呼

    函式選用

    callback 參數如下所示:

    ()=>void

傳回

  • Promise<void>

    Manifest V3 以上版本支援 Promise,但是為了提供回溯相容性而提供的回呼。您無法在同一個函式呼叫中同時使用這兩者。承諾會用傳遞至回呼的同類型解析。

unregisterContentScripts()

Promise Chrome 96 以上版本
chrome.scripting.unregisterContentScripts(
  filter?: ContentScriptFilter,
  callback?: function,
)

為這項擴充功能取消註冊內容指令碼。

參數

  • 過濾器

    如果有指定,系統只會取消註冊符合篩選條件的動態內容指令碼。否則,系統會取消註冊擴充功能的所有動態內容指令碼。

  • 回呼

    函式選用

    callback 參數如下所示:

    ()=>void

傳回

  • Promise<void>

    Manifest V3 以上版本支援 Promise,但是為了提供回溯相容性而提供的回呼。您無法在同一個函式呼叫中同時使用這兩者。承諾會用傳遞至回呼的同類型解析。

updateContentScripts()

Promise Chrome 96 以上版本
chrome.scripting.updateContentScripts(
  scripts: RegisteredContentScript[],
  callback?: function,
)

更新這項擴充功能的一或多個內容指令碼。

參數

  • 包含要更新的指令碼清單。只有現有指令碼中的屬性在此物件中指定屬性時,系統才會更新其屬性。如果剖析/檔案驗證期間發生錯誤,或是指定的 ID 與完整註冊的指令碼不符,系統就不會更新指令碼。

  • 回呼

    函式選用

    callback 參數如下所示:

    ()=>void

傳回

  • Promise<void>

    Manifest V3 以上版本支援 Promise,但是為了提供回溯相容性而提供的回呼。您無法在同一個函式呼叫中同時使用這兩者。承諾會用傳遞至回呼的同類型解析。