Описание
API chrome.debugger служит альтернативным транспортом для протокола удаленной отладки Chrome. Используйте chrome.debugger, чтобы подключиться к одной или нескольким вкладкам и отслеживать сетевое взаимодействие, отлаживать JavaScript, изменять DOM и CSS и т. д. Используйте свойство Debuggee tabId, чтобы настраивать таргетинг на вкладки с помощью sendCommand и перенаправлять события по tabId из обратных вызовов onEvent.
Разрешения
debuggerЧтобы использовать этот API, необходимо объявить разрешение "debugger" в манифесте расширения.
{
"name": "My extension",
...
"permissions": [
"debugger",
],
...
}
Ограничения корпоративных правил
На корпоративных устройствах некоторые правила могут запрещать расширениям подключать отладчик, используя модель "все или ничего" во время подключения (browser.debugger.attach()):
- Ограничения для хостов. Если корпоративное правило
ExtensionSettingsнастраивает заблокированных хостов (runtime_blocked_hosts) для расширения,browser.debugger.attach()блокируется на всех целевых объектах с ошибкой"Host access is restricted by policy."(даже если отдельные источники находятся вruntime_allowed_hosts). - Правила защиты от потери данных и скриншотов. Если корпоративное правило
DisableScreenshotsзапрещает делать скриншоты или если к целевому объекту применяются правила защиты от потери данных,browser.debugger.attach()завершается с ошибкой"Screenshot capture is restricted by policy.".
Основные понятия и использование
После подключения API browser.debugger позволяет отправлять команды протокола Chrome DevTools (CDP) указанному объекту. Подробное описание CDP выходит за рамки этой документации. Чтобы узнать больше, ознакомьтесь с официальной документацией по CDP.
Цели
Цели – это объекты, которые отлаживаются. К ним относятся вкладки, фреймы iframe и рабочие процессы. Каждый целевой объект идентифицируется с помощью UUID и имеет связанный тип (например, iframe, shared_worker и т. д.).
В рамках одной цели может быть несколько контекстов выполнения. Например, фреймы iframe из одного процесса не получают уникальную цель, а представлены как разные контексты, доступ к которым можно получить из одной цели.
Ограниченные домены
Из соображений безопасности API browser.debugger не предоставляет доступ ко всем доменам протокола инструментов разработчика Chrome. Доступны следующие домены: Accessibility, Audits, CacheStorage, Console, CSS, Database, Debugger, DOM, DOMDebugger, DOMSnapshot, Emulation, Fetch, IO, Input, Inspector, Log, Network, Overlay, Page, Performance, Runtime, Storage, Target, Tracing, WebAudio и WebAuthn.
Как работать с рамками
Сопоставление кадров с целями не является однозначным. В рамках одной вкладки несколько фреймов одного и того же процесса могут иметь одну и ту же цель, но использовать разные контексты выполнения. С другой стороны, для iframe, который находится вне процесса, может быть создан новый целевой объект.
Чтобы прикрепить к каждому фрейму, нужно обрабатывать каждый тип фрейма отдельно:
Слушайте событие
Runtime.executionContextCreated, чтобы выявлять новые контексты выполнения, связанные с теми же кадрами процесса.Чтобы определить кадры, которые не относятся к процессу, выполните инструкции по подключению к связанным целям.
Прикрепление к связанным целям
После подключения к целевому объекту вы можете подключиться к другим связанным объектам, в том числе к дочерним фреймам вне процесса или связанным рабочим процессам.
Начиная с Chrome 125 API browser.debugger поддерживает плоские сеансы. Это позволяет добавлять дополнительные цели в качестве дочерних элементов в основную сессию отладчика и отправлять им сообщения без необходимости выполнять ещё один вызов browser.debugger.attach. Вместо этого вы можете добавить свойство sessionId при вызове browser.debugger.sendCommand, чтобы указать дочернее устройство, которому нужно отправить команду.
Чтобы автоматически подключаться к дочерним фреймам, сначала добавьте прослушиватель для события Target.attachedToTarget:
browser.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 browser.debugger.sendCommand(session, "Runtime.enable");
}
});
Затем включите автоматическое подключение, отправив команду Target.setAutoAttach с параметром flatten, установленным на значение true:
await browser.debugger.sendCommand({ tabId }, "Target.setAutoAttach", {
autoAttach: true,
waitForDebuggerOnStart: false,
flatten: true,
filter: [{ type: "iframe", exclude: false }]
});
Автоматическое подключение выполняется только к фреймам, о которых знает цель, а это только те фреймы, которые являются непосредственными дочерними элементами фрейма, связанного с целью. Например, если иерархия фреймов выглядит как A -> B -> C (все фреймы относятся к разным источникам), то при вызове Target.setAutoAttach для целевого объекта, связанного с фреймом A, сеанс также будет привязан к фрейму B. Однако это не рекурсивная функция, поэтому для того, чтобы прикрепить сеанс к C, также необходимо вызвать Target.setAutoAttach для B.
Примеры
Чтобы попробовать этот API, установите пример API отладчика из репозитория chrome-extension-samples.
Типы
Debuggee
Идентификатор отлаживаемого процесса. Необходимо указать tabId, extensionId или targetId.
Свойства
-
extensionId
строка необязательно
Идентификатор расширения, которое вы хотите отладить. Прикрепить отладчик к фоновой странице расширения можно только при использовании параметра командной строки
--silent-debugger-extension-api. -
tabId
number необязательный
Идентификатор вкладки, которую вы хотите отладить.
-
targetId
строка необязательно
Непрозрачный идентификатор целевого объекта отладки.
DebuggerSession
Идентификатор сеанса отладчика. Необходимо указать tabId, extensionId или targetId. Также можно указать необязательный параметр sessionId. Если для аргументов, отправленных из onEvent, указан sessionId, это означает, что событие происходит из сеанса дочернего протокола в рамках корневого сеанса отлаживаемого приложения. Если при передаче в sendCommand указан sessionId, то он будет относиться к дочернему сеансу протокола в рамках корневого сеанса отладки.
Свойства
-
extensionId
строка необязательно
Идентификатор расширения, которое вы хотите отладить. Прикрепить отладчик к фоновой странице расширения можно только при использовании параметра командной строки
--silent-debugger-extension-api. -
sessionId
строка необязательно
Непрозрачный идентификатор сеанса Chrome DevTools Protocol. Идентифицирует дочерний сеанс в корневом сеансе, который определяется с помощью tabId, extensionId или targetId.
-
tabId
number необязательный
Идентификатор вкладки, которую вы хотите отладить.
-
targetId
строка необязательно
Непрозрачный идентификатор целевого объекта отладки.
DetachReason
Причина прекращения подключения.
Перечисление
"target_closed"
"canceled_by_user"
TargetInfo
Информация о целевом объекте отладки
Свойства
-
подключен
Логическое значение
Значение True, если отладчик уже подключен.
-
extensionId
строка необязательно
Идентификатор расширения, если тип равен background_page.
-
faviconUrl
строка необязательно
Целевой URL значка сайта.
-
id
string
Идентификатор цели.
-
tabId
number необязательный
Идентификатор вкладки, определенный, если type == "page".
-
название
string
Заголовок целевой страницы.
-
тип
Тип таргетинга.
-
url
string
Целевой URL.
TargetInfoType
Тип таргетинга.
Перечисление
"page"
"background_page"
"worker"
"other"
Методы
attach()
chrome.debugger.attach(
target: Debuggee,
requiredVersion: string,
): Promise<void>
Подключает отладчик к указанной цели.
Параметры
-
target
Целевой объект отладки, к которому вы хотите подключиться.
-
requiredVersion
string
Требуемая версия протокола отладки ("0.1"). Подключиться к отладчику можно только в том случае, если основная версия совпадает, а промежуточная версия больше или равна. Список версий протокола можно найти здесь.
Возвраты
-
Promise<void>
Chrome 96 и более поздние версииРазрешается, когда операция прикрепления выполнена успешно или завершилась с ошибкой. Объект Promise распознается без значения. Если прикрепить файл не удастся, объект возвращает отказ.
detach()
chrome.debugger.detach(
target: Debuggee,
): Promise<void>
Отсоединяет отладчик от указанной цели.
Параметры
-
target
Цель отладки, от которой нужно отсоединиться.
Возвраты
-
Promise<void>
Chrome 96 и более поздние версииРазрешается, когда операция отсоединения выполнена успешно или произошла ошибка. Объект Promise распознается без значения. Если отсоединить устройство не удастся, объект возвращает отказ.
getTargets()
chrome.debugger.getTargets(): Promise<TargetInfo[]>
Возвращает список доступных целей отладки.
Возвраты
-
Promise<TargetInfo[]>
Chrome 96 и более поздние версии
sendCommand()
chrome.debugger.sendCommand(
target: DebuggerSession,
method: string,
commandParams?: object,
): Promise<object | undefined>
Отправляет указанную команду целевому объекту отладки.
Параметры
-
target
Целевое устройство для отладки, на которое нужно отправить команду.
-
method
string
Название метода. Должен быть одним из методов, определенных протоколом удаленной отладки.
-
commandParams
объект необязательный
Объект JSON с параметрами запроса. Этот объект должен соответствовать схеме параметров удаленной отладки для заданного метода.
Возвраты
-
Promise<object | undefined>
Chrome 96 и более поздние версииТело ответа. Если при отправке сообщения произойдет ошибка, обещание будет отклонено.
События
onDetach
chrome.debugger.onDetach.addListener(
callback: function,
)
Активируется, когда браузер завершает сеанс отладки для вкладки. Это происходит, когда закрывается вкладка или для прикрепленной вкладки вызываются инструменты разработчика Chrome.
Параметры
-
обратный вызов
function
Параметр
callbackвыглядит следующим образом:(source: Debuggee, reason: DetachReason) => void
-
source
-
причина;
-
onEvent
chrome.debugger.onEvent.addListener(
callback: function,
)
Активируется при каждом событии инструментации, связанном с проблемами целевого объекта отладки.
Параметры
-
обратный вызов
function
Параметр
callbackвыглядит следующим образом:(source: DebuggerSession, method: string, params?: object) => void
-
source
-
method
string
-
params
объект необязательный
-