browser.userScripts

說明

使用 userScripts API 在使用者指令碼情境中執行使用者指令碼。

權限

userScripts

如要使用 User Scripts API,請browser.userScripts,將 "userScripts" 權限新增至 manifest.json,並為要執行指令碼的網站新增 "host_permissions"。

{
  "name": "User script test extension",
  "manifest_version": 3,
  "minimum_chrome_version": "120",
  "permissions": [
    "userScripts"
  ],
  "host_permissions": [
    "*://example.com/*"
  ]
}

可用性

Chrome 120 以上版本 瀏覽器* (自 Chrome 148 起) MV3 以上版本

概念和用途

使用者指令碼是插入網頁的程式碼片段,用於修改網頁的外觀或行為。與內容指令碼和 browser.scripting API 等其他擴充功能不同,User Scripts API 可讓您執行任意程式碼。如果擴充功能執行的指令碼由使用者提供,且無法隨附於擴充功能套件,就必須使用這個 API。

啟用 userScripts API

擴充功能取得 userScripts API 的使用權限後,使用者必須啟用特定切換鈕,擴充功能才能使用該 API。具體需要切換的選項,以及停用時的 API 行為,會因 Chrome 版本而異。

請使用下列檢查,判斷使用者需要啟用哪個切換鈕,例如在新使用者新手上路期間:

let version = Number(navigator.userAgent.match(/(Chrome|Chromium)\/([0-9]+)/)?.[2]);
if (version >= 138) {
  // Allow User Scripts toggle will be used.
} else {
  // Developer mode toggle will be used.
}

以下各節將說明不同的切換鈕,以及如何啟用。

Chrome 138 以下版本 (開發人員模式切換鈕)

身為擴充功能開發人員,您已在安裝的 Chrome 中啟用開發人員模式。使用者也必須啟用開發人員模式。

您可以複製下列操作說明,並貼到擴充功能的說明文件中,供使用者參考

  1. 在新分頁中輸入 chrome://extensions,前往「擴充功能」頁面。(根據設計,chrome:// 網址無法連結)。
  2. 按一下「開發人員模式」旁的切換鈕,啟用開發人員模式。

    Chrome 擴充功能頁面,醒目顯示「開發人員模式」切換鈕

    「擴充功能」頁面 (chrome://extensions)

Chrome 138 以上版本 (「允許使用者指令碼」切換鈕)

「允許使用者指令碼」切換鈕位於各個擴充功能的詳細資料頁面 (例如 chrome://extensions/?id=YOUR_EXTENSION_ID)。

您可以將下列操作說明複製並貼到擴充功能的說明文件中,供使用者參考:

  1. 在新分頁中輸入 chrome://extensions,前往「擴充功能」頁面。(根據設計,chrome:// 網址無法連結)。
  2. 按一下擴充功能資訊卡上的「詳細資料」按鈕,即可查看擴充功能的詳細資訊。
  3. 按一下「允許使用者指令碼」旁的切換鈕。
擴充功能詳細資料頁面上的「允許使用者指令碼」切換鈕
「允許使用者指令碼」切換鈕 (chrome://extensions/?id=abc...)

檢查 API 是否可用

建議您執行下列檢查,判斷是否已啟用 userScripts API,因為這項檢查適用於所有 Chrome 版本。這項檢查會嘗試呼叫 browser.userScripts() 方法,當 API 可用時,該方法應一律成功。如果這項呼叫擲回錯誤,表示 API 無法使用:

function isUserScriptsAvailable() {
  try {
    // Method call which throws if API permission or toggle is not enabled.
    browser.userScripts.getScripts();
    return true;
  } catch {
    // Not available.
    return false;
  }
}

在隔離環境中作業

使用者和內容指令碼都可以在獨立環境或主要環境中執行。獨立環境是一種執行環境,主機頁面或其他擴充功能無法存取。這樣一來,使用者指令碼就能變更其 JavaScript 環境,而不會影響主機頁面或其他擴充功能的使用者和內容指令碼。相反地,代管網頁或其他擴充功能的使用者和內容指令碼,也無法看到使用者指令碼 (和內容指令碼)。在主世界中執行的指令碼可供主機頁面和其他擴充功能存取,且可供主機頁面和其他擴充功能查看。如要選取世界,請在呼叫 userScripts.register() 時傳遞 "USER_SCRIPT" 或 "MAIN"。

如要為 USER_SCRIPT 環境設定內容安全政策,請呼叫 userScripts.configureWorld():

browser.userScripts.configureWorld({
  csp: "script-src 'self'"
});

訊息

與內容指令碼和離螢幕文件一樣,使用者指令碼會使用訊息與擴充功能的其他部分通訊 (也就是說,使用者指令碼可以像擴充功能的其他部分一樣呼叫 runtime.sendMessage() 和 runtime.connect())。不過,系統會使用專屬事件處理常式 (也就是不使用 onMessage 或 onConnect) 接收這些事件。這些處理常式稱為 runtime.onUserScriptMessage 和 runtime.onUserScriptConnect。專屬處理常式可讓您更輕鬆地識別來自使用者指令碼的訊息,這類指令碼是較不信任的內容。

傳送訊息前,您必須呼叫 configureWorld(),並將 messaging 引數設為 true。請注意,csp 和 messaging 引數可以同時傳遞。

browser.userScripts.configureWorld({
  messaging: true
});

擴充功能更新

擴充功能更新時,系統會清除使用者指令碼。如要重新加入,請在擴充功能 Service Worker 的 runtime.onInstalled 事件處理常式中執行程式碼。僅回應傳遞至事件回呼的 "update" 原因。

範例

這個範例取自範例存放區中的 userScript 範例。

註冊指令碼

以下範例說明對 register() 的基本呼叫。第一個引數是物件陣列,用於定義要註冊的指令碼。這裡僅顯示部分選項。

browser.userScripts.register([{
  id: 'test',
  matches: ['*://*/*'],
  js: [{code: 'alert("Hi!")'}]
}]);

類型

ExecutionWorld

使用者指令碼執行的 JavaScript 環境。

列舉

"MAIN"
指定 DOM 的執行環境,也就是與主機網頁 JavaScript 共用的執行環境。

"USER_SCRIPT"
指定使用者指令碼專用的執行環境,不受網頁 CSP 限制。

InjectionResult

Chrome 135 以上版本 Chrome 148 起為 browser.*

屬性

  • documentId

    字串

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

  • 錯誤

    字串 選填

    錯誤 (如有)。error 和 result 互斥。

  • frameId

    數字

    與插入相關聯的框架。

  • 結果

    任意 選填

    指令碼執行結果。

InjectionTarget

Chrome 135 以上版本 Chrome 148 起為 browser.*

屬性

  • allFrames

    布林值 選填

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

  • documentIds

    string[] 選填

    要插入的特定 documentId ID。如果已設定 frameIds,則不得設定這個屬性。

  • frameIds

    number[] 選填

    要插入的特定頁框 ID。

  • tabId

    數字

    要插入指令碼的分頁 ID。

RegisteredUserScript

屬性

  • allFrames

    布林值 選填

    如果為 true,則會插入所有頁框,即使該頁框不是分頁中最頂層的頁框也一樣。系統會獨立檢查每個框架是否符合網址規定,如果不符合,就不會插入子框架。預設值為 false,表示只會比對頂層頁框。

  • excludeGlobs

    string[] 選填

    指定萬用字元模式,避免將使用者指令碼插入符合模式的網頁。

  • excludeMatches

    string[] 選填

    排除原本會插入這個使用者指令碼的網頁。如要進一步瞭解這些字串的語法,請參閱「比對模式」。

  • id

    字串

    API 呼叫中指定的使用者指令碼 ID。這個屬性不得以「_」開頭,因為這個前置字元已保留給產生的指令碼 ID。

  • includeGlobs

    string[] 選填

    指定要插入這個使用者指令碼的網頁萬用字元模式。

  • js

    ScriptSource[] 選用

    ScriptSource 物件清單,定義要插入有相符圖像的網頁的指令碼來源。必須為 ${ref:register} 指定這項屬性,且指定時必須是非空白陣列。

  • 完全相符

    string[] 選填

    指定要將這個使用者指令碼插入哪些網頁。如要進一步瞭解這些字串的語法,請參閱「比對模式」。必須為 ${ref:register} 指定這項屬性。

  • runAt

    RunAt 選填

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

  • 世界

    執行指令碼的 JavaScript 執行環境。預設為 `USER_SCRIPT`。

  • worldId

    字串 選填

    Chrome 133 以上版本 Chrome 148 以上版本支援 browser.*

    指定要執行的使用者指令碼世界 ID。如果省略,指令碼會在預設的使用者指令碼環境中執行。只有在省略 world 或設為 USER_SCRIPT 時才有效。開頭為底線 (_) 的值為保留值。

ScriptSource

屬性

  • 程式碼

    字串 選填

    包含要插入的 JavaScript 程式碼的字串。必須明確指定 file 或 code。

  • 檔案

    字串 選填

    要插入的 JavaScript 檔案路徑 (相對於擴充功能的根目錄)。必須明確指定 file 或 code。

UserScriptFilter

屬性

  • ids

    string[] 選填

    getScripts 只會傳回這份清單中指定 ID 的指令碼。

UserScriptInjection

Chrome 135 以上版本 Chrome 148 起為 browser.*

屬性

  • injectImmediately

    布林值 選填

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

  • ScriptSource 物件清單,定義要插入目標的指令碼來源。

  • 指定要插入指令碼的目標詳細資料。

  • 世界

    執行指令碼的 JavaScript「世界」。預設為 USER_SCRIPT。

  • worldId

    字串 選填

    指定要執行的使用者指令碼世界 ID。如果省略,指令碼會在預設的使用者指令碼環境中執行。只有在省略 world 或設為 USER_SCRIPT 時才有效。開頭為底線 (_) 的值為保留值。

WorldProperties

屬性

  • csp

    字串 選填

    指定世界 CSP。預設為 `ISOLATED` 世界 CSP。

  • 訊息

    布林值 選填

    指定是否公開訊息 API。預設為 false。

  • worldId

    字串 選填

    Chrome 133 以上版本 Chrome 148 以上版本支援 browser.*

    指定要更新的使用者指令碼環境 ID。如未提供,則會更新預設使用者指令碼環境的屬性。開頭為底線 (_) 的值為保留值。

方法

configureWorld()

browser.userScripts.configureWorld(
  properties: WorldProperties,
)
: Promise<void>

設定 `USER_SCRIPT` 執行環境。

參數

傳回

  • 承諾<void>

    設定世界後解析的 Promise。

execute()

Chrome 135 以上版本 Chrome 148 起為 browser.*
browser.userScripts.execute(
  injection: UserScriptInjection,
)
: Promise<InjectionResult[]>

將指令碼插入目標結構定義。根據預設,系統會在 document_idle 執行指令碼,如果網頁已載入,則會立即執行。如果設定 injectImmediately 屬性,即使網頁尚未載入完成,指令碼也會直接插入,不會等待。如果指令碼評估為 Promise,瀏覽器會等待 Promise 解決並傳回結果值。

參數

傳回

getScripts()

browser.userScripts.getScripts(
  filter?: UserScriptFilter,
)
: Promise<RegisteredUserScript[]>

傳回這個擴充功能的所有動態註冊使用者指令碼。

參數

  • 篩選器

    如果指定,這個方法只會傳回相符的使用者指令碼。

傳回

  • Promise 會解析已註冊的指令碼。如果發生錯誤,系統會拒絕承諾。

getWorldConfigurations()

Chrome 133 以上版本 Chrome 148 以上版本支援 browser.*
browser.userScripts.getWorldConfigurations(): Promise<WorldProperties[]>

擷取所有已註冊的世界設定。

傳回

  • Promise<WorldProperties[]>

    Promise,會解析為已註冊的世界設定。

register()

browser.userScripts.register(
  scripts: RegisteredUserScript[],
)
: Promise<void>

為這個擴充功能註冊一或多個使用者指令碼。

參數

傳回

  • 承諾<void>

    指令碼完整註冊後,Promise 就會解析。如果發生錯誤,系統會拒絕承諾。

resetWorldConfiguration()

Chrome 133 以上版本 Chrome 148 以上版本支援 browser.*
browser.userScripts.resetWorldConfiguration(
  worldId?: string,
)
: Promise<void>

重設使用者指令碼環境的設定。任何插入指定 ID 環境的指令碼,都會使用預設環境設定。

參數

  • worldId

    字串 選填

    要重設的使用者指令碼環境 ID。如省略,則會重設預設世界的設定。

傳回

  • 承諾<void>

    在重設設定時解析的 Promise。

unregister()

browser.userScripts.unregister(
  filter?: UserScriptFilter,
)
: Promise<void>

取消註冊這個擴充功能的所有動態註冊使用者指令碼。

參數

  • 篩選器

    如有指定,這個方法只會取消註冊相符的使用者指令碼。

傳回

  • 承諾<void>

    指令碼完全取消註冊後,Promise 就會解析。如果發生錯誤,系統會拒絕承諾。

update()

browser.userScripts.update(
  scripts: RegisteredUserScript[],
)
: Promise<void>

更新這項擴充功能的一或多個使用者指令碼。

參數

  • 指令碼

    包含要更新的使用者指令碼清單。只有在這個物件中指定的屬性,才會在現有指令碼中更新。如果指令碼剖析/檔案驗證期間發生錯誤,或指定的 ID 未對應至完整註冊的指令碼,則不會更新任何指令碼。

傳回

  • 承諾<void>

    指令碼完全更新後,Promise 就會解析。如果發生錯誤,系統會拒絕承諾。