説明
chrome.debugger API は、Chrome の リモート デバッグ プロトコルの代替トランスポートとして機能します。chrome.debugger を使用して 1 つ以上のタブに接続し、ネットワーク インタラクションの計測、JavaScript のデバッグ、DOM と CSS の変更などを行います。sendCommand でタブをターゲットにするには、Debuggee プロパティ tabId を使用し、onEvent コールバックから tabId でイベントをルーティングします。
権限
debuggerこの API を使用するには、拡張機能のマニフェストで "debugger" 権限を宣言する必要があります。
{
"name": "My extension",
...
"permissions": [
"debugger",
],
...
}
エンタープライズ ポリシーの制限
エンタープライズ デバイスでは、一部のポリシーにより、アタッチ時
(chrome.debugger.attach())に拡張機能がデバッガをアタッチできない場合があります。
- ホストの制限: エンタープライズ ポリシー
ExtensionSettingsで拡張機能のブロックされたホスト(runtime_blocked_hosts)が構成されている場合、chrome.debugger.attach()はすべてのターゲットでブロックされ、エラー"Host access is restricted by policy."が発生します(個々のオリジンがruntime_allowed_hostsに含まれている場合でも同様です)。 - スクリーンショットと DLP のポリシー: エンタープライズ ポリシー
DisableScreenshotsでスクリーンショットのキャプチャが無効になっている場合、またはデータ損失防止(DLP)ルールがターゲットに適用されている場合、chrome.debugger.attach()は失敗し、エラー"Screenshot capture is restricted by policy."が発生します。
コンセプトと使用方法
アタッチすると、chrome.debugger API を使用して、Chrome DevTools Protocol
(CDP)コマンドを特定のターゲットに送信できます。CDP の詳細については、このドキュメントの範囲外です。CDP の詳細については、
CDP の公式ドキュメントをご覧ください。
ターゲット
ターゲットは、デバッグ対象を表します。これには、タブ、iframe、ワーカーなどが含まれます。各ターゲットは UUID で識別され、関連付けられたタイプ(iframe、shared_worker など)があります。
ターゲット内には複数の実行コンテキストが存在する場合があります。たとえば、同じプロセス iframe は一意のターゲットを取得しませんが、単一のターゲットからアクセスできる異なるコンテキストとして表されます。
制限付きドメイン
セキュリティ上の理由から、chrome.debugger API はすべての Chrome DevTools Protocol ドメインへのアクセスを提供しません。使用可能なドメインは、Accessibility、
Audits、CacheStorage、Console、
CSS、Database、Debugger、DOM、
DOMDebugger、DOMSnapshot、
Emulation、Fetch、IO、Input、
Inspector、Log、Network、Overlay、
Page、Performance、Profiler、
Runtime、Storage、Target、Tracing、
WebAudio、WebAuthn です。
フレームの操作
フレームとターゲットの 1 対 1 のマッピングはありません。1 つのタブ内で、 複数の同じプロセス フレームが同じターゲットを共有する場合がありますが、異なる 実行コンテキストを使用します。一方、アウトオブプロセス iframe の場合は、新しいターゲットが作成されることがあります。
すべてのフレームにアタッチするには、フレームのタイプごとに個別に処理する必要があります。
Runtime.executionContextCreatedイベントをリッスンして、同じプロセス フレームに関連付けられた新しい実行コンテキストを特定します。関連するターゲットにアタッチする手順に沿って、アウトオブプロセス フレームを 特定します。
関連するターゲットにアタッチする
ターゲットに接続したら、アウトオブプロセスの子フレームや関連するワーカーなど、関連するターゲットにさらに接続することが必要になる場合があります。
Chrome 125 以降では、chrome.debugger API がフラット セッションをサポートしています。これにより、メインのデバッガ セッションに子として追加のターゲットを追加し、chrome.debugger.attach を再度呼び出すことなくメッセージを送信できます。代わりに、chrome.debugger.sendCommand を呼び出すときに sessionId プロパティを追加して、コマンドを送信する子ターゲットを特定できます。
アウトオブプロセスの子フレームに自動的にアタッチするには、まず Target.attachedToTarget イベントのリスナーを追加します。
chrome.debugger.onEvent.addListener((source, method, params) => {
if (method === "Target.attachedToTarget") {
// `source` identifies the parent session, but we need to construct a new
// identifier for the child session
const session = { ...source, sessionId: params.sessionId };
// Call any needed CDP commands for the child session
await chrome.debugger.sendCommand(session, "Runtime.enable");
}
});
次に、自動アタッチを有効にするには、Target.setAutoAttachコマンドを
使用して、flattenオプションをtrueに設定します。
await chrome.debugger.sendCommand({ tabId }, "Target.setAutoAttach", {
autoAttach: true,
waitForDebuggerOnStart: false,
flatten: true,
filter: [{ type: "iframe", exclude: false }]
});
自動アタッチは、ターゲットが認識しているフレームにのみアタッチされます。これは、関連付けられたフレームの直接の子であるフレームに限定されます。たとえば、フレーム階層 A -> B -> C(すべてクロスオリジン)の場合、A に関連付けられたターゲットに対して Target.setAutoAttach を呼び出すと、セッションも B にアタッチされます。ただし、これは再帰的ではないため、セッションを C にアタッチするには、B に対して Target.setAutoAttach も呼び出す必要があります。
例
この API を試すには、デバッガ API のサンプルをchrome-extension-samples リポジトリからインストールします。
型
Debuggee
デバッグ対象の ID。tabId、extensionId、targetId のいずれかを指定する必要があります。
プロパティ
-
extensionId
文字列(省略可)
デバッグする拡張機能の ID。拡張機能のバックグラウンド ページへのアタッチは、
--silent-debugger-extension-apiコマンドライン スイッチを使用した場合にのみ可能です。 -
tabId
数値(省略可)
デバッグするタブの ID。
-
targetId
文字列(省略可)
デバッグ ターゲットの不透明な ID。
DebuggerSession
デバッガ セッション ID。tabId、extensionId、targetId のいずれかを指定する必要があります。また、sessionId を指定することもできます。`onEvent` から送信された引数に sessionId が指定されている場合、イベントはルート デバッグ対象セッション内の子プロトコル セッションから送信されます。`sendCommand` に渡すときに sessionId を指定すると、ルート デバッグ対象セッション内の子プロトコル セッションがターゲットになります。
プロパティ
-
extensionId
文字列(省略可)
デバッグする拡張機能の ID。拡張機能のバックグラウンド ページへのアタッチは、
--silent-debugger-extension-apiコマンドライン スイッチを使用した場合にのみ可能です。 -
sessionId
文字列(省略可)
Chrome DevTools Protocol セッションの不透明な ID。tabId、extensionId、targetId で識別されるルート セッション内の子セッションを識別します。
-
tabId
数値(省略可)
デバッグするタブの ID。
-
targetId
文字列(省略可)
デバッグ ターゲットの不透明な ID。
DetachReason
接続終了の理由。
列挙型
"target_closed"
"canceled_by_user"
TargetInfo
デバッグ ターゲット情報
プロパティ
-
attached
ブール値
デバッガがすでにアタッチされている場合は true。
-
extensionId
文字列(省略可)
拡張機能 ID。type = 'background_page' の場合に定義されます。
-
faviconUrl
文字列(省略可)
ターゲットのファビコン URL。
-
id
文字列
ターゲット ID。
-
tabId
数値(省略可)
タブ ID。type == 'page' の場合に定義されます。
-
title
文字列
ターゲット ページのタイトル。
-
type
ターゲット タイプ。
-
url
文字列
ターゲット URL。
TargetInfoType
ターゲット タイプ。
列挙型
"page"
"background_page"
"worker"
"other"
メソッド
attach()
chrome.debugger.attach(
target: Debuggee,
requiredVersion: string,
): Promise<void>
指定されたターゲットにデバッガをアタッチします。
パラメータ
-
ターゲット
アタッチするデバッグ ターゲット。
-
requiredVersion
文字列
必要なデバッグ プロトコルのバージョン(「0.1」)。アタッチできるのは、メジャー バージョンが一致し、マイナー バージョンがそれ以上のデバッグ対象のみです。プロトコル バージョンの一覧については、こちらをご覧ください。
戻り値
-
Promise<void>
Chrome 96 以降アタッチ オペレーションが成功または失敗すると解決されます。Promise は値なしで解決されます。アタッチに失敗した場合、Promise は拒否されます。
パラメータ
-
ターゲット
切り離すデバッグ ターゲット。
戻り値
-
Promise<void>
Chrome 96 以降切り離しオペレーションが成功または失敗すると解決されます。Promise は値なしで解決されます。切り離しに失敗した場合、Promise は拒否されます。
戻り値
-
Promise<TargetInfo[]>
Chrome 96 以降
sendCommand()
chrome.debugger.sendCommand(
target: DebuggerSession,
method: string,
commandParams?: object,
): Promise<object | undefined>
指定されたコマンドをデバッグ ターゲットに送信します。
パラメータ
-
ターゲット
コマンドを送信するデバッグ ターゲット。
-
method
文字列
メソッド名。リモート デバッグ プロトコルで定義されているメソッドのいずれかである必要があります。
-
commandParams
オブジェクト(省略可)
リクエスト パラメータを含む JSON オブジェクト。このオブジェクトは、指定されたメソッドのリモート デバッグ パラメータ スキーマに準拠している必要があります。
戻り値
-
Promise<object | undefined>
Chrome 96 以降レスポンス本文。メッセージの投稿中にエラーが発生した場合、Promise は拒否されます。
イベント
onDetach
chrome.debugger.onDetach.addListener(
callback: function,
)
ブラウザがタブのデバッグ セッションを終了したときに発生します。これは、タブが閉じられた場合、またはアタッチされたタブに対して Chrome DevTools が呼び出された場合に発生します。
パラメータ
-
callback
関数
callbackパラメータは次のようになります:(source: Debuggee, reason: DetachReason) => void
-
ソース
-
reason
-
onEvent
chrome.debugger.onEvent.addListener(
callback: function,
)
デバッグ ターゲットが計測イベントを発行するたびに発生します。
パラメータ
-
callback
関数
callbackパラメータは次のようになります:(source: DebuggerSession, method: string, params?: object) => void
-
ソース
-
method
文字列
-
params
オブジェクト(省略可)
-