說明
使用 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/*"
]
}
可用性
概念和用途
使用者指令碼是插入網頁的程式碼片段,用於修改網頁的外觀或行為。與內容指令碼和 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 中啟用開發人員模式。使用者也必須啟用開發人員模式。
您可以複製下列操作說明,並貼到擴充功能的說明文件中,供使用者參考
- 在新分頁中輸入
chrome://extensions,前往「擴充功能」頁面。(根據設計,chrome://網址無法連結)。 按一下「開發人員模式」旁的切換鈕,啟用開發人員模式。
「擴充功能」頁面 (chrome://extensions)
Chrome 138 以上版本 (「允許使用者指令碼」切換鈕)
「允許使用者指令碼」切換鈕位於各個擴充功能的詳細資料頁面 (例如 chrome://extensions/?id=YOUR_EXTENSION_ID)。
您可以將下列操作說明複製並貼到擴充功能的說明文件中,供使用者參考:
- 在新分頁中輸入
chrome://extensions,前往「擴充功能」頁面。(根據設計,chrome://網址無法連結)。 - 按一下擴充功能資訊卡上的「詳細資料」按鈕,即可查看擴充功能的詳細資訊。
- 按一下「允許使用者指令碼」旁的切換鈕。
檢查 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
屬性
-
documentId
字串
與插入作業相關聯的文件。
-
錯誤
字串 選填
錯誤 (如有)。
error和result互斥。 -
frameId
數字
與插入相關聯的框架。
-
結果
任意 選填
指令碼執行結果。
InjectionTarget
屬性
-
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
屬性
-
injectImmediately
布林值 選填
是否應盡快在目標中觸發注入。請注意,這不保證指令碼會在載入網頁前插入,因為指令碼到達目標時,網頁可能已經載入。
-
js
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()
browser.userScripts.execute(
injection: UserScriptInjection,
): Promise<InjectionResult[]>
將指令碼插入目標結構定義。根據預設,系統會在 document_idle 執行指令碼,如果網頁已載入,則會立即執行。如果設定 injectImmediately 屬性,即使網頁尚未載入完成,指令碼也會直接插入,不會等待。如果指令碼評估為 Promise,瀏覽器會等待 Promise 解決並傳回結果值。
參數
-
注射避孕針
傳回
-
Promise<InjectionResult[]>
getScripts()
browser.userScripts.getScripts(
filter?: UserScriptFilter,
): Promise<RegisteredUserScript[]>
傳回這個擴充功能的所有動態註冊使用者指令碼。
參數
-
篩選器
如果指定,這個方法只會傳回相符的使用者指令碼。
傳回
-
Promise<RegisteredUserScript[]>
Promise 會解析已註冊的指令碼。如果發生錯誤,系統會拒絕承諾。
getWorldConfigurations()
browser.userScripts.getWorldConfigurations(): Promise<WorldProperties[]>
擷取所有已註冊的世界設定。
傳回
-
Promise<WorldProperties[]>
Promise,會解析為已註冊的世界設定。
register()
browser.userScripts.register(
scripts: RegisteredUserScript[],
): Promise<void>
為這個擴充功能註冊一或多個使用者指令碼。
參數
-
指令碼
包含要註冊的使用者指令碼清單。
傳回
-
承諾<void>
指令碼完整註冊後,Promise 就會解析。如果發生錯誤,系統會拒絕承諾。
resetWorldConfiguration()
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 就會解析。如果發生錯誤,系統會拒絕承諾。