chrome.debugger

Opis

Interfejs chrome.debugger API służy jako alternatywny transport dla protokołu zdalnego debugowania Chrome. Użyj chrome.debugger, aby dołączyć do co najmniej 1 karty i instrumentować interakcję z siecią, debugować JavaScript, modyfikować DOM i CSS oraz wykonywać inne czynności. Użyj właściwości Debuggee tabId, aby kierować na karty za pomocą sendCommand i przekierowywać zdarzenia według tabId z wywołań zwrotnych onEvent.

Uprawnienia

debugger

Aby korzystać z tego interfejsu API, musisz zadeklarować uprawnienie "debugger" w pliku manifestu rozszerzenia.

{
  "name": "My extension",
  ...
  "permissions": [
    "debugger",
  ],
  ...
}

Ograniczenia wynikające z zasad dla firm

Na urządzeniach firmowych niektóre zasady mogą ograniczać możliwość dołączania debugera przez rozszerzenia za pomocą modelu „wszystko albo nic” w momencie dołączania (chrome.debugger.attach()):

  • Ograniczenia dotyczące hosta: jeśli zasady firmowe ExtensionSettings konfigurują zablokowane hosty (runtime_blocked_hosts) dla rozszerzenia, chrome.debugger.attach() jest blokowane na wszystkich celach z błędem "Host access is restricted by policy." (nawet jeśli poszczególne źródła znajdują się w runtime_allowed_hosts).
  • Zasady dotyczące zrzutów ekranu i DLP: jeśli zasady firmowe DisableScreenshots wyłączają przechwytywanie zrzutów ekranu lub do celu mają zastosowanie reguły zapobiegania utracie danych (DLP), chrome.debugger.attach() kończy się niepowodzeniem z błędem "Screenshot capture is restricted by policy.".

Pojęcia i użycie

Po dołączeniu interfejs chrome.debugger API umożliwia wysyłanie poleceń protokołu narzędzi deweloperskich w Chrome (CDP) do danego celu. Szczegółowe wyjaśnienie CDP wykracza poza zakres tej dokumentacji. Aby dowiedzieć się więcej o CDP, zapoznaj się z oficjalną dokumentacją CDP.

Cele

Cele reprezentują coś, co jest debugowane. Może to być karta, element iframe lub instancja robocza. Każdy cel jest identyfikowany przez UUID i ma powiązany typ (np. iframe, shared_worker itp.).

W ramach celu może występować wiele kontekstów wykonania. Na przykład elementy iframe w tym samym procesie nie mają unikalnego celu, ale są reprezentowane jako różne konteksty, do których można uzyskać dostęp z jednego celu.

Ograniczone domeny

Ze względów bezpieczeństwa interfejs chrome.debugger API nie zapewnia dostępu do wszystkich domen protokołu narzędzi deweloperskich w Chrome. Dostępne domeny to: 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 i WebAuthn.

Praca z ramkami

Nie ma mapowania ramek na cele 1:1. W ramach jednej karty, wiele ramek w tym samym procesie może współdzielić ten sam cel, ale używać innego kontekstu wykonania. Z drugiej strony, w przypadku elementu iframe poza procesem można utworzyć nowy cel.

Aby dołączyć do wszystkich ramek, musisz osobno obsługiwać każdy typ ramki:

  • Nasłuchuj zdarzenia Runtime.executionContextCreated, aby identyfikować nowe konteksty wykonania powiązane z ramkami w tym samym procesie.

  • Aby identyfikować ramki poza procesem, wykonaj czynności opisane w sekcji Dołączanie do powiązanych celów.

Po połączeniu z celem możesz chcieć połączyć się z innymi powiązanymi celami, w tym z ramkami podrzędnymi poza procesem lub powiązanymi instancjami roboczymi.

Od Chrome 125 interfejs chrome.debugger API obsługuje sesje płaskie. Umożliwia to dodawanie dodatkowych celów jako elementów podrzędnych do głównej sesji debugowania i wysyłanie do nich wiadomości bez konieczności wykonywania kolejnego wywołania chrome.debugger.attach. Zamiast tego możesz dodać właściwość sessionId podczas wywoływania chrome.debugger.sendCommand, aby zidentyfikować cel podrzędny, do którego chcesz wysłać polecenie.

Aby automatycznie dołączać do ramek podrzędnych poza procesem, najpierw dodaj odbiornik zdarzenia 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");
  }
});

Następnie włącz automatyczne dołączanie, wysyłając polecenie Target.setAutoAttach z opcją flatten ustawioną na true:

await chrome.debugger.sendCommand({ tabId }, "Target.setAutoAttach", {
  autoAttach: true,
  waitForDebuggerOnStart: false,
  flatten: true,
  filter: [{ type: "iframe", exclude: false }]
});

Automatyczne dołączanie dołącza tylko do ramek, o których wie cel, czyli tylko do ramek, które są bezpośrednimi elementami podrzędnymi ramki z nim powiązanej. Na przykład w przypadku hierarchii ramek A -> B -> C (gdzie wszystkie są współdzielone) wywołanie Target.setAutoAttach dla celu powiązanego z A spowoduje, że sesja zostanie też dołączona do B. Nie jest to jednak rekurencyjne, więc aby dołączyć sesję do C, należy też wywołać Target.setAutoAttach dla B.

Przykłady

Aby wypróbować ten interfejs API, zainstaluj przykład interfejsu Debugger API z repozytorium chrome-extension-samples.

Typy

Debuggee

Identyfikator debugowanego obiektu. Należy określić tabId, extensionId lub targetId.

Właściwości

  • extensionId

    string optional

    Identyfikator rozszerzenia, które chcesz debugować. Dołączenie do strony w tle rozszerzenia jest możliwe tylko wtedy, gdy używany jest przełącznik wiersza poleceń --silent-debugger-extension-api.

  • tabId

    number optional

    Identyfikator karty, którą chcesz debugować.

  • targetId

    string optional

    Nieprzezroczysty identyfikator celu debugowania.

DebuggerSession

Chrome 125+

Identyfikator sesji debugowania. Należy określić tabId, extensionId lub targetId. Opcjonalnie można też podać sessionId. Jeśli sessionId jest określony w argumentach wysyłanych z onEvent, oznacza to, że zdarzenie pochodzi z sesji protokołu podrzędnego w ramach sesji debugowania głównego. Jeśli sessionId jest określony podczas przekazywania do sendCommand, kieruje on do sesji protokołu podrzędnego w ramach sesji debugowania głównego.

Właściwości

  • extensionId

    string optional

    Identyfikator rozszerzenia, które chcesz debugować. Dołączenie do strony w tle rozszerzenia jest możliwe tylko wtedy, gdy używany jest przełącznik wiersza poleceń --silent-debugger-extension-api.

  • sessionId

    string optional

    Nieprzezroczysty identyfikator sesji protokołu narzędzi deweloperskich w Chrome. Identyfikuje sesję podrzędną w ramach sesji głównej zidentyfikowanej przez tabId, extensionId lub targetId.

  • tabId

    number optional

    Identyfikator karty, którą chcesz debugować.

  • targetId

    string optional

    Nieprzezroczysty identyfikator celu debugowania.

DetachReason

Chrome 44+

Powód zakończenia połączenia.

Typ wyliczeniowy

"target_closed"

"canceled_by_user"

TargetInfo

Informacje o celu debugowania

Właściwości

  • attached

    boolean

    Prawda, jeśli debuger jest już dołączony.

  • extensionId

    string optional

    Identyfikator rozszerzenia, zdefiniowany, jeśli type = 'background_page'.

  • faviconUrl

    string optional

    Adres URL faviconu celu.

  • id

    string

    Identyfikator celu.

  • tabId

    number optional

    Identyfikator karty, zdefiniowany, jeśli type == 'page'.

  • title

    string

    Tytuł strony docelowej.

  • Typ celu.

  • url

    string

    Adres URL celu.

TargetInfoType

Chrome 44+

Typ celu.

Typ wyliczeniowy

"page"

"background_page"

"worker"

"other"

Metody

attach()

chrome.debugger.attach(
  target: Debuggee,
  requiredVersion: string,
)
: Promise<void>

Dołącza debuger do danego celu.

Parametry

  • target

    Cel debugowania, do którego chcesz się dołączyć.

  • requiredVersion

    string

    Wymagana wersja protokołu debugowania („0.1”). Można dołączyć tylko do debugowanego obiektu z pasującą wersją główną i wersją podrzędną większą lub równą. Listę wersji protokołu znajdziesz tutaj.

Zwraca

  • Promise<void>

    Chrome 96+

    Rozwiązuje się, gdy operacja dołączania zakończy się powodzeniem lub niepowodzeniem. Obietnica jest rozwiązywana bez wartości. Jeśli dołączenie się nie powiedzie, obietnica zostanie odrzucona.

detach()

chrome.debugger.detach(
  target: Debuggee,
)
: Promise<void>

Odłącza debuger od danego celu.

Parametry

  • target

    Cel debugowania, od którego chcesz się odłączyć.

Zwraca

  • Promise<void>

    Chrome 96+

    Rozwiązuje się, gdy operacja odłączania zakończy się powodzeniem lub niepowodzeniem. Obietnica jest rozwiązywana bez wartości. Jeśli odłączenie się nie powiedzie, obietnica zostanie odrzucona.

getTargets()

chrome.debugger.getTargets(): Promise<TargetInfo[]>

Zwraca listę dostępnych celów debugowania.

Zwraca

sendCommand()

chrome.debugger.sendCommand(
  target: DebuggerSession,
  method: string,
  commandParams?: object,
)
: Promise<object | undefined>

Wysyła podane polecenie do celu debugowania.

Parametry

  • Cel debugowania, do którego chcesz wysłać polecenie.

  • method

    string

    Nazwa metody. Powinna to być jedna z metod zdefiniowanych przez protokół zdalnego debugowania.

  • commandParams

    object optional

    Obiekt JSON z parametrami żądania. Ten obiekt musi być zgodny ze schematem parametrów zdalnego debugowania dla danej metody.

Zwraca

  • Promise<object | undefined>

    Chrome 96+

    Treść odpowiedzi. Jeśli podczas wysyłania wiadomości wystąpi błąd, obietnica zostanie odrzucona.

Wydarzenia

onDetach

chrome.debugger.onDetach.addListener(
  callback: function,
)

Uruchamiane, gdy przeglądarka kończy sesję debugowania karty. Dzieje się tak, gdy karta jest zamykana lub gdy dla dołączonej karty wywoływane są Narzędzia deweloperskie w Chrome.

Parametry

onEvent

chrome.debugger.onEvent.addListener(
  callback: function,
)

Uruchamiane, gdy cel debugowania wyśle zdarzenie instrumentacji.

Parametry

  • callback

    function

    Parametr callback wygląda tak:

    (source: DebuggerSession, method: string, params?: object) => void