chrome.debugger

说明

chrome.debugger API 可作为 Chrome 的 远程调试协议的替代传输方式。使用 chrome.debugger 连接到一个或多个标签页,以检测网络互动、调试 JavaScript、更改 DOM 和 CSS 等。使用 Debuggee 属性 tabId 通过 sendCommand 定位标签页,并通过 onEvent 回调中的 tabId 路由事件。

权限

debugger

您必须在扩展程序的清单中声明 "debugger" 权限,才能使用此 API。

{
  "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 或 worker。每个目标都由 UUID 标识,并具有关联的类型(例如 iframeshared_worker 等)。

在一个目标中,可能存在多个执行上下文。例如,如果 iframe 位于同一进程中,则不会获得唯一的目标,而是表示为可从单个目标访问的不同上下文。

受限网域

出于安全考虑,chrome.debugger API 不提供对所有 Chrome DevTools Protocol 网域的访问权限。可用的网域包括:AccessibilityAuditsCacheStorageConsoleCSSDatabaseDebuggerDOMDOMDebuggerDOMSnapshotEmulationFetchIOInputInspectorLogNetworkOverlayPagePerformanceProfilerRuntimeStorageTargetTracingWebAudioWebAuthn

使用帧

帧与目标之间没有一对一的映射关系。在单个标签页中, 多个位于同一进程中的帧可能会共享同一目标,但使用不同的 执行上下文。另一方面,系统可能会为进程外 iframe 创建新目标。

如需连接到所有帧,您需要分别处理每种类型的帧:

  • 监听 Runtime.executionContextCreated 事件,以识别与位于同一进程中的帧关联的新执行上下文。

  • 按照连接到相关目标中的步骤操作,以识别进程外帧

连接到目标后,您可能需要连接到更多相关目标,包括进程外子帧或关联的 worker。

从 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");
  }
});

然后,将 flatten 选项设置为 true,发送 Target.setAutoAttach 命令以启用 自动连接

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。不过,这不是递归的,因此还需要为 B 调用 Target.setAutoAttach,才能将会话连接到 C。

示例

如需试用此 API,请从 chrome-extension-samples 代码库安装调试器 API 示例

类型

Debuggee

调试对象标识符。必须指定 tabId、extensionId 或 targetId

属性

  • extensionId

    字符串 可选

    您打算调试的扩展程序的 ID。只有在使用 --silent-debugger-extension-api 命令行开关时,才能连接到扩展程序后台页面。

  • tabId

    数字 可选

    您打算调试的标签页的 ID。

  • targetId

    字符串 可选

    调试目标的不透明 ID。

DebuggerSession

Chrome 125 及更高版本

调试器会话标识符。必须指定 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

Chrome 44 及更高版本

连接终止原因。

枚举

"target_closed"

"canceled_by_user"

TargetInfo

调试目标信息

属性

  • attached

    布尔值

    如果调试器已连接,则为 True。

  • extensionId

    字符串 可选

    扩展程序 ID,如果 type = 'background_page',则定义此 ID。

  • faviconUrl

    字符串 可选

    目标网站图标网址。

  • id

    字符串

    目标 ID。

  • tabId

    数字 可选

    标签页 ID,如果 type == 'page',则定义此 ID。

  • title

    字符串

    目标网页标题。

  • 目标类型。

  • url

    字符串

    目标网址。

TargetInfoType

Chrome 44 及更高版本

目标类型。

枚举

"page"

"background_page"

"worker"

"other"

方法

attach()

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

将调试器连接到给定目标。

参数

  • target

    您要连接的调试目标。

  • requiredVersion

    字符串

    所需的调试协议版本 ("0.1")。只能连接到主要版本匹配且次要版本大于或等于的调试对象。您可以在此处获取协议版本列表。

返回

  • Promise<void>

    Chrome 96 及更高版本

    在连接操作成功或失败后解析。Promise 解析时没有值。如果连接失败,Promise 将被拒绝。

detach()

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

从给定目标分离调试器。

参数

  • target

    您要从中分离的调试目标。

返回

  • Promise<void>

    Chrome 96 及更高版本

    在分离操作成功或失败后解析。Promise 解析时没有值。如果分离失败,Promise 将被拒绝。

getTargets()

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

返回可用调试目标的列表。

返回

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 开发者工具时,会发生这种情况。

参数

onEvent

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

每当调试目标发出检测事件时触发。

参数

  • callback

    函数

    callback 参数如下所示:

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