Описание
API chrome.debugger служит альтернативным транспортом для протокола удаленной отладки Chrome. Используйте chrome.debugger, чтобы подключиться к одной или нескольким вкладкам и отслеживать сетевое взаимодействие, отлаживать JavaScript, изменять DOM и CSS и выполнять другие действия. Используйте свойство tabId Debuggee, чтобы настроить таргетинг на вкладки с помощью sendCommand и маршрутизировать события по tabId из обратных вызовов onEvent.
Разрешения
debuggerЧтобы использовать этот API, необходимо объявить разрешение "debugger" в манифесте расширения.
{
"name": "My extension",
...
"permissions": [
"debugger",
],
...
}
Ограничения правил Enterprise
На корпоративных устройствах некоторые правила могут запрещать расширениям подключать отладчик по принципу "все или ничего" во время подключения (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 (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
Строка (необязательно)
Идентификатор расширения, заданный, если type = 'background_page'.
-
faviconUrl
Строка (необязательно)
URL целевого значка сайта.
-
id
string
Идентификатор цели.
-
tabId
number (необязательно)
Идентификатор вкладки, определенный, если type == 'page'.
-
название
string
Заголовок целевой страницы.
-
тип
Тип таргетинга.
-
url
string
Целевой URL.
TargetInfoType
Тип таргетинга.
Перечисление
"page"
"background_page"
"worker"
"other"
Методы
attach()
browser.debugger.attach(
target: Debuggee,
requiredVersion: string,
): Promise<void>
Подключает отладчик к указанной цели.
Параметры
-
target
Цель отладки, к которой вы хотите подключиться.
-
requiredVersion
string
Требуемая версия протокола отладки ("0.1"). Подключиться к отлаживаемому процессу можно только с соответствующей основной версией и промежуточной версией, которая не ниже, чем у отлаживаемого процесса. Список версий протокола можно найти здесь.
Возвраты
-
Promise<void>
Chrome 96 и более поздние версии browser.* начиная с Chrome 148Разрешается, когда операция прикрепления завершается успешно или с ошибкой. Объект Promise распознается без значения. Если прикрепить не удастся, объект Promise будет отклонен.
detach()
browser.debugger.detach(
target: Debuggee,
): Promise<void>
Отключает отладчик от указанной цели.
Параметры
-
target
Цель отладки, от которой нужно отсоединиться.
Возвраты
-
Promise<void>
Chrome 96 и более поздние версии browser.* начиная с Chrome 148Разрешается, когда операция отсоединения завершается успешно или с ошибкой. Объект Promise распознается без значения. Если отсоединение не удается выполнить, объект возвращает отказ.
getTargets()
browser.debugger.getTargets(): Promise<TargetInfo[]>
Возвращает список доступных целей отладки.
Возвраты
-
Promise<TargetInfo[]>
Chrome 96 и более поздние версии browser.* начиная с Chrome 148
sendCommand()
browser.debugger.sendCommand(
target: DebuggerSession,
method: string,
commandParams?: object,
): Promise<object | undefined>
Отправляет указанную команду в цель отладки.
Параметры
-
target
Цель отладки, которой нужно отправить команду.
-
method
string
Название метода. Должен быть одним из методов, определенных протоколом удаленной отладки.
-
commandParams
Объект (необязательно)
Объект JSON с параметрами запроса. Этот объект должен соответствовать схеме параметров удаленной отладки для заданного метода.
Возвраты
-
Promise<object | undefined>
Chrome 96 и более поздние версии browser.* начиная с Chrome 148Тело ответа. Если при публикации сообщения произойдет ошибка, обещание будет отклонено.
События
onDetach
browser.debugger.onDetach.addListener(
callback: function,
)
Срабатывает, когда браузер завершает сеанс отладки для вкладки. Это происходит, когда вкладка закрывается или для нее вызываются инструменты разработчика Chrome.
Параметры
-
обратный вызов
function
Параметр
callbackвыглядит следующим образом:(source: Debuggee, reason: DetachReason) => void
-
source
-
reason
-
onEvent
browser.debugger.onEvent.addListener(
callback: function,
)
Срабатывает, когда целевой объект отладки выдает событие инструментирования.
Параметры
-
обратный вызов
function
Параметр
callbackвыглядит следующим образом:(source: DebuggerSession, method: string, params?: object) => void
-
source
-
method
string
-
params
Объект (необязательно)
-