通过 CDP 进行网站观测¶
已捕获的 Debugger 源码可通过 export_web_scripts 导出,供 REA 现有的静态 JavaScript 分析使用。有关捕获选项、源映射以及浏览器/本地解析限制,请参阅捕获的网站脚本。使用捕获的模块关系在显式 URL/import-map 上下文下解析一个已导出脚本的原生导入。
REA 可以通过 Chrome DevTools 协议 (CDP) 附加到用户自有的 Chrome 系列浏览器,并针对现有页面生成有界 Evidence。这是一种被动的逆向工程能力,而非通用的浏览器自动化或远程控制面。
关于请求/响应体与流量调试,请参阅 Fiddler Everywhere 捕获与 MCP。可使用 REA 离线检查原生 SAZ 或 HAR 1.2,或连接 Everywhere 独立的 MCP 服务器。
HTTP 发现和浏览器 WebSocket 输入需要显式端口。显式的默认端口 :80 仍然有效,并保留在规范端点中;省略端口仍然无效。当可选元数据格式错误时,HTTP /json/list 发现会保留可用的同级项:附加状态变为未知,行/字段诊断信息出现在 limitations 中。在选择和连接之前,目标身份与套接字权威分别得到独立验证。
内置功能¶
list_browser_targets/rea list-browser-targets默认发现端点处的所有合格页面目标,可选用精确来源过滤器。inspect_web_page/rea inspect-web-page捕获 DOM 结构、无障碍节点、脚本、资源、安全响应/DOM 元数据、附加窗口网络和控制台元数据、WebSocket 帧大小、worker、配额,以及可选的选定存储键名、脱敏的存储内容指纹或脚本源码。analyze_web_bundle/rea analyze-web-bundle在不执行的情况下解析选定的脚本产物,并推导出 chunk 边、路由和端点候选、供应商指纹、静态 WebMCP 声明,以及可选的 source-map/原始源码证据。observe_web_session/rea observe-web-session为外部用户操作设置一个请求时长的观察窗口,并记录有序的重新加载、SPA 导航、重定向、失败、生命周期和目标终止元数据。-
discover_webmcp_tools/rea discover-webmcp-tools使用实验性的 CDP WebMCP 域返回观察到的范围内注册项、其完整观察到的input_schema声明,并内联返回规范的input_schema_sha256摘要。声明是不可信的 JSON 数据,包括声明的类型、必填字段、枚举、示例和参考 URL。REA 不解析 schema 引用。省略可选的inputSchema是有效的无参数注册,以 null schema 和摘要表示。这些字段取代input_schema_shape。在不同观察帧中具有相同名称和 URL 的注册项保留各自独立的身份。tool_key包含观察到的帧 ID;它不是跨导航或浏览器会话的稳定身份。同帧注册更新仅替换该所有者,移除则使其他所有者保持完整。声明的readOnly、untrustedContent、consequential和autosubmit注解提示按注册项逐一报告:true/false是声明值,null表示该声明在本次捕获中未提供此提示,而缺少consequential键则表示该提示未被记录——要么是历史捕获中未记录,要么是因为观察到的注解无效。请查阅发现的完整性与排除项,以区分这些情况。格式错误的注解值或注册栈会保留注册项,但覆盖范围不完整,并带有invalid_protocol_value排除项。其他格式错误的协议负载可能导致发现显式失败。REA 从不暴露WebMCP.invokeTool。 -
compare_web_captures/rea compare-web-captures比较被动捕获或精确步骤对齐的浏览器场景。场景结果应用可复现的字面量规范化,并暴露对齐失败,以及产物级别的操作、截图、DOM、无障碍、URL、历史、存储和事件差异。缺失或截断的证据绝不会被视为等价。
对于紧凑的路由查询,请选择 detail: "summary" 和 view: {kind: "javascript-routes", collection: "routes", limit: 20}。共享的路由清单保留源 ID、精确位置、部分覆盖以及完整的父级 Evidence,供后续过滤页面使用。静态候选永远不会确立完整的应用覆盖范围或可达性。
对于 analyze_web_bundle,每个 webmcp_declarations 条目的 schema_property_names 是静态已知自有属性键的源派生投影,而非 schema 验证。schema_property_names_coverage 报告该投影的完整程度:complete 表示字面量 properties 对象已被完整枚举(包括空字面量);partial 表示字面量对象可用,但某些计算或展开成员未被解析,名称数组保留已知键;unknown 表示 schema 或 properties 所有者无法作为对象字面量枚举,包括显式非对象值;not_present 表示在 inputSchema ?? input_schema 别名选择之后,不存在有效的 schema 或自有 properties 成员。not_present 仅描述此投影:它不验证 schema,也不排除通过其他 schema 构造表达的属性。较旧的观察可能省略覆盖字段;应将省略视为 unknown,而不是从数组推断完整性。
被动 DOM 比较独立检查完整的节点清单和完整的帧父子结构。帧 ID 和同级枚举顺序是捕获局部的,不构成变更;重复 ID、缺失父级和循环祖先关系仍然未知。完整的帧差异仍可在 DOM 节点不完整时证明变更,反之亦然。部分 DOM 或元数据收集摘要不能证明修改:缺失节点或链接可能源于协议遗漏。被拒绝的 DOM 事实也会使派生的 URL 和 agent-hint 元数据不完整,而来自其他节点和文档的有效事实仍保留在捕获中。
页面网络和控制台覆盖范围分别独立地从来自该域的第一个已观察事件或其成功的启用确认开始。捕获的生命周期开始时间更早,并且不建立域的可用性。在启用回复之前收到的事件仍属于观察的一部分。
Worker 输出是最终的目标清单快照。attached 描述任何调试客户端,而不是 REA 拥有的观察会话。所选页面会话收集器不收集 worker 会话的请求、控制台事件或脚本,并且快照前已消失的 worker 可能缺失;因此 worker 覆盖范围受附加(attach)限制。缺失的所有权元数据报告为 unattributed_target,且 worker 归属不可用,这与经证实的外部所有者被排除为 out_of_target_scope 是分开的。仅凭共享来源并不能建立任何一种关系。
被动比较将查找标识、跨捕获对应关系、内容证据和清单覆盖范围分开:
| 观察项 | 比较结果 |
|---|---|
| 重命名的 WebMCP 工具键/frame ID,且有一个匹配的名称、所有者来源和 frame URL | 比较注册内容;本地 ID 不能证明变更 |
| 具有相同名称、来源和 frame URL 的重复 WebMCP 所有者 | 对应关系未知;完整的组计数差异仍可证明变更 |
| 匹配的脚本清单键以及保留的源摘要 | 即使没有生产者哈希,也比较保留的 SHA-256 值 |
| 某个对应脚本源不可用,或源和生产者哈希均不可用 | 源相等性仍未知;清单变更和其他已证实的差异仍然有效 |
| 部分 HTTP 响应组是完整对等组的子集 | 未知;省略的重复响应可以解释该差异 |
| 在完整对等组中缺少一个已观察到的 HTTP 响应指纹 | 已变更;遗漏无法解释该保留的响应 |
| WebSocket 连接或 frame 清单不完整 | 不要按位置对齐保留的负载 |
存储指纹在哈希前先解码支持的 CDP 原始值/JSON 值。调试器描述、预览和远程引用并不代表存储内容。具有这些名称的实际 JSON 属性仍然是内容。仅引用对象、不支持的值和不透明的 cookie 分区标识仍是不完整的。先前导出的指纹不会重新计算;在比较跨越此解码器变更生成的捕获时,请重新捕获两侧。
带有 projection_version: 2 的 IndexedDB 模式指纹包含观察到的数据库版本和对象存储定义。缺失、格式错误或不精确的版本会使模式指纹不完整,同时保留观察到的存储事实。没有此标记的历史指纹仅覆盖对象存储:匹配的历史哈希不能确定数据库版本未更改,历史哈希也不会与带版本信息的哈希进行比较。要完成完整的 IndexedDB 版本比较,请重新捕获两侧;其他已证实的存储变更仍可报告。
脚本比较按报告的 URL 对观察结果进行分组,并比较无序的内容样本。生产者清单键包含可选元数据,因此变更后的键本身不能证明脚本被移除或添加。缺失的模块、长度、语言或源哈希事实仍为未知;共享的已知值和完整的保留源摘要仍可证明组变更。部分清单使用与重复 HTTP 样本相同的省略规则。WebMCP 丢弃工具计数也阻止相等性,两个不完整的所有者清单不能仅凭其不同的保留注册来证明工具对应关系。
capture_web_screenshot/rea capture-web-screenshot返回一个内容寻址的可见视口 PNG。compare_web_screenshots/rea compare-web-screenshots执行有界的本地 PNG 像素比较,不借助 OCR 或外部服务。- CLI 比较命令接受每个捕获、截图工件或规范化策略作为内联 JSON 或 JSON 文件路径。对于截图工件和场景捕获,请使用文件,因为其中嵌入的 PNG 字节可能超过主机的命令行长度限制。
- 每个接口面都有等效的 CLI 和 MCP 契约,并返回 Evidence 出处。
- MCP 工具内联返回完整结果并包含 Evidence ID。会话证据可以通过
export_evidence_bundle导出。
目标发现在一个结果中返回完整的范围内目标数组。
屏幕截图比较内存预算¶
compare_web_screenshots 在解压任一图像之前,会根据 256 MiB 的预估工作内存预算接纳两个 PNG。这是该操作的处理缓冲区预算,不是 PNG 尺寸限制、CDP 传输限制或进程 RSS 保证。超过预算且头部有效的尺寸将返回 resource_constraint,并包含 details.resource: "memory" 以及预估和最大工作集字节数。无效的 PNG 结构仍属于格式错误的输入;超出受支持像素比较范围的编码仍属于不支持目标的错误。
该保守估算包括:两个解码器拥有的解码输入缓冲区、当前图像的拼接 IDAT 缓冲区、Node zlib 默认 16 KiB 输出块的后备存储(按保留块向上取整)、拼接的 inflate 结果在其输出块保留期间、zlib 检查 maxOutputLength 之前可能的一个额外输出块、未过滤的扫描线存储、RGB 到 RGBA 的扩展,以及在解码第二个图像时第一个保留的 RGBA 图像。RGBA 输出别名指向其未过滤缓冲区,并且只计数一次。准入计算在分配图像大小的内存之前使用带检查的整数运算。调用方拥有的 JSON/base64 字符串、输入解析和验证、传输缓冲区、垃圾回收器行为以及其他运行时内存不在此估算范围内;该预算不承诺总进程内存的上限。
Electron file:// 页面使用独立的提供程序与目标边界;参见 electron-observation.md。
提供程序权限¶
CDP 页面捕获和 V8 Inspector 观察会附加到已在运行的目标上,而无需启动它、驱动操作或评估目标代码。Playwright 场景在提供程序拥有的浏览器或调用方选择的外部浏览器中驱动操作,并捕获步骤快照。独立的提供程序保留了这些权限与生命周期差异。它们共享同一套排除词汇表(BrowserExclusionReason):每个拒绝原因都映射到该词汇表,即使线上协议模式保留了更窄的历史分类。
被动页面和 Inspector 捕获会启用 Debugger 域。目标的 debugger 语句随后可暂停执行;这些观察路径不会使用 Debugger.setSkipAllPauses 抑制暂停,也不会恢复目标。它们缺少显式暂停命令,因此不保证执行不会中断。
CDP 附加并不能保证浏览器保留所有状态。当 REA 的页面会话断开时,Chromium 可能清除另一个客户端的 navigator.platform 模拟,即使该会话没有发送任何模拟命令。这会影响页面检查、bundle 捕获、会话观察、截图、WebMCP 发现和 Electron 页面检查;仅列出目标不会附加页面会话。REA 无法读取其他客户端的完整 user-agent/client-hint 配置,也不会重放猜测的设置。当需要保留外部配置的模拟时,请使用一次性浏览器,或让拥有该配置的客户端事后重新应用其完整配置。参见 复现与 Chromium 所有权限制。
现有的静态应用 Evidence 以及被动的 Web/Electron 捕获,稍后可通过 JavaScript 静态/运行时对账 组合起来。
启动浏览器¶
使用显式调试端口启动独立的浏览器配置。确切的可执行文件名因平台和安装方式而异:
google-chrome \
--remote-debugging-port=9222 \
--user-data-dir=/tmp/rea-browser-profile \
http://127.0.0.1:3000
REA 不会启动、拥有或终止此浏览器。请使用专用配置,并在调查完成后自行停止它。不要将调试端口暴露在非回环接口上。
其他 Chromium 系列浏览器(例如 Chromium 或 Brave)使用同样的两个标志,工作方式相同。在 macOS 上,运行应用程序包内的可执行文件,例如
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" 或
"/Applications/Brave Browser.app/Contents/MacOS/Brave Browser"。Fedora 将 Chromium 安装为 chromium-browser。
REA 通过浏览器在回环端口上的 HTTP 发现端点进行附加;对于某些被动工具,则通过
浏览器 socket 附加。连接失败报告
endpoint_unreachable;可访问的 HTTP 服务如果返回非 200 或非 JSON 的发现响应,则报告 invalid_endpoint_response。
在精简的 Linux 容器中,Xvfb 下的有头 Chromium 可能持续运行,但其 DevTools 端口始终未打开。请安装 GLES、EGL 和 Mesa DRI 库(在 Fedora 上为 libglvnd-gles、mesa-libEGL 和 mesa-dri-drivers),然后重启浏览器。
在 Linux 上,可访问但已锁定的桌面密钥环可能使 Chrome 在首次导航前停滞。对于专用调查配置,请添加 --password-store=basic 以绕过该密钥环。此时空或占位框架 URL 描述的是未加载的页面;REA 仍要求使用被允许且已提交的 URL。参见 启动问题调查。
无 HTTP 发现的浏览器¶
某些浏览器暴露了回环浏览器 WebSocket,但不提供 /json/version 或 /json/list。Chrome 144 及更高版本可从 chrome://inspect/#remote-debugging 在已运行的浏览器上启用远程调试;据报道,此模式仅提供浏览器 socket。自 Chrome 136 起,--remote-debugging-port 对默认配置被忽略,因此这是检查现有配置中页面的剩余方式。
对于此类浏览器,请传入浏览器 socket 而不是 HTTP 端点:
Chrome 会将端口和 /devtools/browser/<id> 路径写入其用户数据目录中的 DevToolsActivePort 文件。REA 不会替你读取该文件。
- 只有
list_browser_targets、inspect_web_page、analyze_web_bundle、observe_web_session、discover_webmcp_tools和capture_web_screenshot接受浏览器 socket。网站运行时归属、Electron 检查和场景附加模式仍需要 HTTP 发现。 - 每次调用打开一个 WebSocket,并将其用于发现(
Browser.getVersion、Target.getTargets)以及选定的页面。发现必须在与 HTTP 发现相同的 10 秒时限内完成。Chrome 可能会要求你批准每次连接。 - 浏览器标识符控制对 socket 的访问。Evidence 将端点记录为
ws://127.0.0.1:9222/devtools/browser/[REDACTED]。 browser.revision是 socket 的Browser.getVersion值,例如@e533e98…。HTTP 发现报告WebKit-Version,例如537.36 (@e533e98…)。Target.getTargets报告每个目标是否已附加。Chrome 的/json/list可能省略该信息,因此 HTTP 发现可能将attached报告为null。- 现有配置可能包含许多不相关的页面。目标列表返回每个合格页面的 URL 和标题,因此请传入
--allowed-origins以仅列出你正在调查的来源。
仅通过 --remote-debugging-pipe 或供应商私有自动化通道驱动的浏览器不具备任一端点,REA 无法附加到它。要检查此类页面,请在以 --remote-debugging-port 启动的 Chromium 系列浏览器中复现它。
请求边界¶
CDP 连接对每条 WebSocket 消息强制执行共享的 64 MiB 限制。更大的回复(包括来自 Chrome 的有效回复)会因 payload_limit 失败。该限制统计的是 JSON 解析前的消息字节数;它并不限制解码后的字符串或 JSON 对象所占用的内存。
发现过程提供的是字面环回 CDP 端点,并返回所有符合条件的页面目标,除非精确的 HTTP(S) 源过滤器收窄了结果。后续检查请求会选择单个目标;其默认范围是该目标当前的源。端点要么是 http://127.0.0.1:PORT,要么是浏览器套接字 ws://127.0.0.1:PORT/devtools/browser/ID;[::1] 可替代 127.0.0.1。localhost、私有局域网地址、HTTPS 和 wss: 端点、凭据、查询、片段、隐式端口以及任何其他路径都不是有效的 CDP 端点。源过滤器只包含协议、主机和端口;路径、凭据、查询、片段和通配符都不是有效的源。
CLI 工作流¶
每次调用都传入端点与所选目标。源过滤器可选,用于收窄目标集。
rea list-browser-targets http://127.0.0.1:9222 --json
rea inspect-web-page http://127.0.0.1:9222 TARGET_ID \
--observation-ms 1000 \
--json
被动观察会在运行时的定时器范围内使用可取消等待来满足请求的持续时间。长时间窗口会在多次连续等待之间保持待定状态;调用方取消、目标终止或离开允许的源都会提前结束收集。window_elapsed 表示所请求等待已完成。
静态包分析与用户驱动的观察窗口是分开的操作:
rea analyze-web-bundle http://127.0.0.1:9222 TARGET_ID \
--json
rea observe-web-session http://127.0.0.1:9222 TARGET_ID \
--observation-ms 10000 --json
rea discover-webmcp-tools http://127.0.0.1:9222 TARGET_ID \
--json
WebMCP 发现前提条件¶
discover_webmcp_tools 只报告所连接浏览器的实验性 WebMCP CDP 域所暴露的内容。当浏览器拒绝未知域时,结果会报告 status: "unavailable"。页面能否注册工具取决于多个不可互换的条件:
- 站点自身的 origin-trial 令牌可以为该源启用 API,前提是该试用仍然有效、浏览器版本和平台支持它,并且用户设置允许它——仅存在令牌并不能保证启用。该试用已宣布适用于 Chrome 149 及更高版本。
WebMCPTesting特性——启动时传入--enable-features=WebMCPTesting,或在普通配置文件中打开chrome://flags/#enable-webmcp-testing——会在该浏览器实例的页面侧启用此 API,与每个站点的令牌无关。在一次试点运行中,某个站点存在注册代码,但其提供的令牌限定为第三方使用;该站点在默认启动下注册了 0 个工具,在该标志下注册了 4 个工具。该令牌没有让第一方文档获得试用资格,这与上述情况一致,但这属于推断,而非实测的 Chrome 行为。
具体到 Chrome 154(一个已测试版本),WebMCP.enable 在默认启动下作出了响应——该调试域在本次运行中并未受标志位门控。其他版本可能不同,因此对于无法归因的零工具结果,只有在确认域可用之后,才应将其解读为注册状态。
发现过程是仅附加(attach-only)的:该命令需要可达的环回 CDP 端点以及来自 list_browser_targets 的目标 ID,并且它绝不会导航、重新加载或评估页面。在你想测量的状态下观察页面;已注册的工具反映协议实际交付的内容。如果发现过程附加时已存在范围内的子框架,webmcp_tools 仍然受附加限制:Chromium 回放可能会省略其较早的注册。后来的实时注册保留其框架所有权,但不能恢复那些缺失的描述符。REA 不会通过重新加载、评估或调用工具来填补这一缺口。
辅助功能名称/描述、控制台原始文本、JSON 主体结构、WebSocket 结构、脚本内容和存储键名都是独立选择的:
rea inspect-web-page http://127.0.0.1:9222 TARGET_ID \
--include-accessibility-text \
--include-console-text \
--include-json-body-shapes \
--include-websocket-shapes \
--include-script-sources \
--include-storage-keys --include-storage-fingerprints \
--json
辅助功能文本、脚本内容、查询值以及显式请求的控制台原始文本可能包含应用程序机密,并成为返回证据的一部分。URL 中的用户名/密码凭据会被移除;普通查询值、片段和参数顺序保持不变。JSON 和 WebSocket 捕获保留完整的路径、类型和数量,绝不包含值或示例。即使请求捕获键名,存储值仍会被遮蔽。--include-storage-fingerprints 请求 SHA-256 身份/值指纹;只有在 cookie、DOM 存储、IndexedDB 和 Cache Storage 都被完整捕获时,这些指纹才支持比较。
截图捕获会将完整可见视口作为内联图像产物返回:
MCP 输入¶
未指定的观察窗口和捕获选项使用保守默认值。仅在调查需要这些额外内容时才设置选项。收集数量不设上限。逐值验证、所选观察窗口和 CDP 协议限制仍然适用;任何不完整或被截断的值都会在结果中报告。
先调用 list_browser_targets,因为目标 ID 是浏览器实例特定的。REA 会在附加前立即重新检查所选目标的当前类型和源。若没有源过滤器,发现过程会列出所有符合条件的页面;单个捕获默认使用所选页面当前的源。
REA 在启用 Runtime、Debugger 或 Network 观察之前建立主框架源边界,在文档捕获前重新检查,并在之后再次验证。如果在最终捕获期间主框架发生导航,REA 丢弃混合结果并返回 target_changed。
观察到的导航也优先于来自过期文档读取的失败,例如因重新加载而失效的脚本 ID;取消仍然是取消。在导航稳定后重试,或者如果所选页面已被替换,则刷新目标发现。来自页面检查、运行时观察、截图和 WebMCP 发现的源范围拒绝会说明允许的 HTTP(S) 源范围,并指示调用方选择允许的文档或明确修改 allowed_origins。页面捕获在后来的文档读取失败时也会保留观察到的主框架范围违规。未解析的初始主框架不构成源违规;其有界启动重试保留不同的拒绝。
截图捕获需要有效的主框架标识。格式错误的标识会产生协议失败;可读的子框架不能替代主框架。
web 会话时间线使用 CDP 单调秒,前提是事件产生者提供可比较的时间戳;缺失或无效的时间戳为 null,而不是人为的零。REA 对窗口边界进行采样时缓冲的事件,仅当其时间戳将其置于该边界之后时才被保留;较旧的事件被排除。没有可比较时间戳的缓冲事件可以保留为上下文证据,带有 timestamp: null,并附有限制说明:它不能确证所选窗口内的活动。主框架范围强制仍适用于上下文导航事件。当带时间戳的下一个请求事件落在窗口内时,网络重定向事件保留其配对的上一跳响应上下文。预启动时间线缓冲区以原始 CDP 消息字节为界。如果在该预算用尽后时钟采样才完成,操作返回 payload_limit,而不是部分窗口。取消和时钟请求失败保留各自的结果。会话 load_failed 行需要先前观察到的主框架 Document 请求;子资源、子框架请求以及未被确认具有请求所有权的失败均被排除。重定向复用其请求身份,已完成/失败的请求释放该身份。活动请求身份元数据使用现有的 8 MiB 保留事件配额;耗尽时明确使观察失败,而不是猜测范围。
数据最小化¶
响应元数据独立解析重复的 CDP 头字段行。Link 投影按顺序保留它们的声明。csp.directives 按顺序列出每个 CSP 策略的指令,跨越字段行和逗号分隔的策略,不记录策略边界,因此指令名称可以重复。单值策略字段将其行合并为一个逗号分隔的值,如 RFC 9110 所规定。每个链接将其目标保留在 href 中,并将其关系上下文保留在 context_url 中,带有单独的 context_scope;缺失的 anchor 使用响应 URL,而相对的 anchor 相对于该 URL 解析。带锚点的链接仍保留在投影中,但仅当解析后的上下文在移除用户信息凭据之前与响应 URL 匹配时,才发出 link_rel 代理提示。遵循 RFC 8288,rel、anchor 和 type 参数使用其首次出现,带引号对的转义按 RFC 9110 §5.6.4 的规定解码。读取较旧的已保存捕获时,上下文字段是可选的。URI 目标或带引号参数内的逗号仍属于这些值的一部分。well-known 资源提示需要精确的支持路径名;路径大小写被保留,因为大小写变体可能标识不同的 HTTP 资源。COOP 和 COEP 投影在验证完整的结构化字段项(包括 report-to 等参数)后保留精确声明的令牌。这些是声明,而非对文档有效策略的评估;缺失、格式错误或非令牌项投影为 null。
REA 保留本地观察数据,并且仅移除 URL 用户信息凭据、显式声明的场景机密,以及来自结构化凭据/存储字段的值:
- URL 观察保留完整的本地 URL,包括查询值、片段、重复参数及其顺序。仅移除用户名/密码用户信息;格式错误的原始 URL 字符串保持可用,
origin: null。 - DOM 快照保留节点类型、节点名称、值长度和属性名称,但不保留文本或属性值。
- 受支持的 DOM URL 属性作为解析后的目标分别投影。HTML 或 XHTML 表单上的空
action以及 HTML 或 XHTML 提交控件上的空formaction解析为文档 URL;其他相对 URL 属性相对于所捕获文档的基础 URL 解析。 - 默认保留无障碍结构和已报告的角色,而名称和描述需要
include_accessibility_text: true。浏览器协议可能省略某个单独的角色;该角色在比较中保持未知。其他观察到的无障碍差异仍可确立变更。 - 网络观察保留方法、状态、MIME 类型、大小、类型、发起方堆栈位置以及移除用户信息凭据后的完整 URL。CDP 报告的重定向按顺序附加为同一请求 ID 上的
redirects,包含先前请求 URL、CDP 响应 URL、方法/类型、响应状态/MIME/编码长度、请求时间戳以及下一个requestWillBeSent事件时间戳。CDP 随该下一个请求事件一同传送redirectResponse,因此后者是事件边界,而非精确的响应时间戳。重定向响应头和响应体会被丢弃;所选源之外的中转跳将与请求链一起丢弃。在长度/编码、结构化 CSP/Link/策略字段和不受信任的代理提示的允许列表投影之后,头字段被丢弃。Cookie 和授权头永远不会保留。 - 请求/响应体默认不会被请求或解析。选中时,仅读取允许来源的 JSON 媒体类型,立即转换为完整的无值类型化路径、类型和观察计数,然后丢弃。每个路径段要么是
{ "kind": "property", "name": "raw property name" },要么是{ "kind": "array-element" };数组元素类型包括基本类型和嵌套数组。字面量*属性与数组元素保持区别。除非选中 JSON 体形状捕获,否则永远不会发送Network.getResponseBody。CDP 通过hasPostData报告但未在postData中提供、或无法解析为 JSON 的 JSON 类型请求体,会使json_body_shapes不可用。当仅捕获了该请求的响应形状时,其body_shapes.status为partial而非included。Base64 响应字节在 JSON 解释之前必须是有效的 UTF-8;无效字节使响应形状不可用,并保留任何观察到的请求形状和网络元数据。生产者解码的字符串和真正的 U+FFFD 字符保留其报告的含义。比较仅当双方捕获都选中了体形状时使用体形状,并且仅在双方观察都提供这些事实时才比较请求/响应形状。不可用或截断的选中覆盖范围使等价性未知;观察到的差异仍报告为已变更。 对于双方都具有完整请求清单的规范化被动输入,即使选定的体形状、响应元数据或 WebSocket 覆盖范围不可用,请求的添加和移除仍可观察。HTTP 请求与 WebSocket 清单覆盖范围分别评估;完整的 HTTP 覆盖范围不能证明缺少某个 WebSocket 连接。有限清单中缺少请求不能证明不存在;完整对端中缺少某个保留请求则可以证明发生了变更。此比较规则不会使实时 CDP 的附加受限清单变得完整,也不会确立体形状的等价性。HTTP 资源类型不可用也会使请求身份不完整:具有相同方法和 URL 的观察仍可能是跨类型的匹配,而相同的未知类型无法确立完全等价。模糊的类型组同样无法证明成员关系或内容变更:缺失的类型可能在桶之间重新分配重复请求,而不改变请求本身。它们的比较保持未知,而独立识别的组保留已证实的变更。不同的方法/URL 以及完整空白的对端清单仍然支持不存在的主张。相关的丢弃事件计数也会限制清单完整性,即使没有某个部分被列为截断:HTTP 使用network_requests,WebSocket 使用websocket_connections和websocket_frames。其他事件类型以及合计总数的丢弃本身不会限制 HTTP 清单。尽管清单不完整,已证实的修改仍然可以报告。重复的 HTTP 样本保留多重性。包含在完整对端中的部分组不能证明修改,即使省略的响应具有不同内容。完整对端中缺失的保留样本可以证明修改。两个部分组仅凭各自不同的保留样本无法确立响应对应关系。WebSocket 流清单和连接计数同样需要完整的 WebSocket 覆盖范围。仅当连接/帧清单完整时才比较保留的帧位置;仅匹配方向/操作码序列并不能证明丢弃后的对齐。重定向资源类型仅使用共享的已知元数据:省略的类型使等价性未知,而不是证明修改。 - 带堆栈来源的控制台观察保留调用类型、参数类型、CDP
Runtime.Timestamp(Unix 纪元以来的毫秒数)以及源位置。缺失或无效的时间戳为null,并使console_events不完整;观察到的零仍然为零。参数类型按 CDP 参数位置列出。缺失或非数组的参数清单为null,格式错误的参数将其位置保持为unknown;任一情况都会使console_events不完整,而观察到的空清单保持为[]。格式错误的堆栈或顶层堆栈帧不会被其调用方替换:该控制台事件被排除,并且请求发起方位置或 WebMCPregistration_source为null;每个都报告为invalid_protocol_value。这个纪元毫秒时钟与observe-web-session中的单调秒时间戳是分开的。当选中控制台文本捕获时,已传递的基本类型值按其原始argument_index逐字保留;对象、getter 和远程属性永远不会展开。当参数清单未知时,文本捕获为unavailable。 - WebSocket 观察保留方向、操作码和负载字节长度。缺失或格式错误的 CDP 操作码返回为
null,依赖操作码的负载字节长度和形状也为null,并将websocket_frames标记为不完整。缺失或类型错误的负载数据不会被当作空数据;其字节长度为null,文本负载形状未知。数字操作码0和观察到的空负载与缺失数据保持区别。操作码在公共检查架构中可为 null,因此客户端必须处理未知协议值。当选中形状捕获时,文本消息被分类为文本或完整的无值 JSON 形状;二进制字节、哈希、前缀和原始负载永远不会保留。 - 存储观察始终脱敏值。键名、IndexedDB 名称和缓存名称需要
include_storage_keys;稳定内容指纹需要额外的include_storage_fingerprints选择。Cookie 指纹覆盖适用于当前主框架 URL(包括其路径)的 Cookie,而不是该源上的每个 Cookie 路径。其他存储仍以源为范围。缓存指纹对所有解码后的响应字节进行哈希,包括 64 KiB 以上的响应体,受每消息 64 MiB CDP 限制约束。缺失或无法解码的缓存体以及不完整的 IndexedDB 远程对象会使指纹覆盖不完整,因此相同观察保持为unknown。
不可用或格式错误的存储清单会将 storage_keys 标记为不可用,即使没有指纹也是如此。比较操作会抑制推断出的键新增和删除,同时保留由双方完整指纹证明的修改。先前导出的捕获不会被追溯修正;请重新捕获以获取这些覆盖标记。
仅当 CDP 在允许的来源上提供 URL 时,脚本元数据才会被包含。稳定键排除瞬态的 CDP 脚本 ID,而精确的瞬态原始 URL 仅用于脚本/资源对账。无 URL 的脚本因无法确定其来源而被排除。当 CDP 提供执行上下文关联时,被接受的脚本会保留其授权的帧 ID 以供后续归因。脚本元数据准入将保留的身份和源映射字符串限制为 8 MiB 和 50,000 条记录。当源映射 URL 无法容纳时,脚本身份仍然保留,源映射覆盖范围报告 resource_budget_exhausted;被拒绝的脚本观测会被计数但不保留其 ID。除非明确请求,否则不包含源代码内容;源代码以自验证工件的形式内联返回,并附带其 SHA-256 摘要。
所选来源范围之外的帧、资源、脚本、事件和工作线程均被排除。显式的 allowed_origins 列表可以包含额外的来源;被排除的目标详情会被计数但不会暴露。
保留的工作线程在 CDP 提供时包含经过验证的开启者目标 ID 和父帧 ID;这些关系不会扩展精确来源边界,也不能证明静态模块所有权。
没有任何一种关系的工作线程会被隐藏,并带有 unattributed_target 排除项,且 workers 出现在 unavailable_sections 中:同源的 URL 并不能确定哪个页面拥有某个工作线程。如果提供的是与另一个目标或帧的关系,则仍属于 out_of_target_scope。当工作线程 URL 为空时,缺失的所有权也仍然未知;被隐藏的目标详情不会被返回。
完整性与限制¶
默认检查窗口为 500 毫秒;调用者选择其持续时间。捕获返回范围内的帧、DOM 和可访问性节点、被接受的脚本、资源、工作线程、存储名称,以及观察到的网络、控制台和 WebSocket 事件。完整的选中文本、脚本源代码和 JSON 形状将内联返回。结果区分 complete_within_window、policy_filtered、attach_limited 和 truncated 覆盖范围。它会报告被排除的项以及因验证和资源限制而被省略或截断的任何值。被省略的脚本元数据会使受影响的部分被明确标记为截断。不允许的来源条目在保留之前即被过滤。
脚本元数据和选定的源代码读取使用一个固定的已接受脚本快照。当最终 CDP 读取完成时仍被保留的新范围内脚本 ID 会计入 scripts.total 和 completeness.dropped_events.scripts,并且 scripts 会被标记为截断;它们不会延长源代码读取过程。同一 ID 的重复延迟事件只计数一次。原始快照不会被后续对现有 ID 的更新所替换或缩减。这些省略并不意味着源代码字节或时间预算已被耗尽。
选定的脚本源代码收集在捕获过程中共享 32 MiB 的 UTF-8 聚合保留预算和 command_timeout_ms 截止时间(默认 20000 毫秒)。字节预算没有运行时覆盖。过大的源代码会被省略,而之后较小的源代码仍可能被容纳。当截止时间到期时,剩余的源代码读取会被跳过。脚本元数据、逐项省略原因和 script_sources 完整性仍然可用。单个 CDP 响应在源代码准入前仍可具体化至单独的 64 MiB 传输限制;保留预算不限制该临时分配。
打包解析和语义检查在自有子进程中顺序执行,不执行捕获的代码。这些是独立的阶段。max_heap_mb 默认为 1024 MiB 的 V8 旧空间(范围 128..16384)。analysis_timeout_ms 默认为每个脚本 30000 毫秒,包括启动和传输。total_analysis_timeout_ms 默认为整个脚本分析的 300000 毫秒。超过有效总计的每脚本截止时间将被拒绝。失败或超时的脚本成为显式的未知,而已完成的结果和后续脚本仍然可用。总截止时间到期会返回带有部分 Evidence 的类型化超时,并标识未启动的脚本。source_map_fetch_timeout_ms 默认为 30000,是一个单项限制,而非分析超时。这些控制也可以作为带有连字符名称的 CLI 标志使用。工作线程协议和结果字节预算没有运行时覆盖。
每个 REA 进程一次只接受一个 Web 打包捕获/分析。已完成的脚本结果共享 8 MiB 的序列化传输预算,在解码和验证另一个结果之前会检查主机堆预留。当主机预留先达到零时,失败会指明堆余量和剩余固定预算。当 8 MiB 配额本身被耗尽时,失败会指明该固定预算并说明其没有运行时覆盖。任一停止都会终止后续脚本启动,并返回类型化的资源失败,包含已完成的事实和显式的未启动脚本未知项。工作线程控制帧限制为 64 KiB。清理必须确认子进程终止后才能释放其私有文件;失败的清理会保留其确切所有者,并阻止替换,直到重试成功。取消会保留已完成的打包事实,包括最终清理期间的取消。
工作线程堆设置不是进程族 RSS 限制。Node 强制执行 V8 旧空间标志;Bun 会忽略它们。Windows 上的 Bun 则使用自有进程提交限制,并带有 512 MiB 运行时储备;其他 Bun 主机没有强制的内存限制。在达到该 Windows 限制之前的分配失败仍会指明配置的限制,并说明尚未达到该限制。这些边界不会在其他 REA 操作或外部进程中建立聚合的主机内存限制。
资源树清单区分有效的空 resources 数组与缺失或格式错误的集合。无效的资源条目会被省略,并导致覆盖不完整,而来自该帧和其他帧的有效资源仍然可用。比较不完整的资源清单无法证明添加、移除或相等性;完整的空清单可以证明移除。资源记录需要非空类型和字符串 MIME 类型;缺失或格式错误的必填字段会被记录为遗漏,而不是臆造默认值。显式空的 MIME 类型是有效的。可选的内容大小可以缺失;无效的提供大小在资源覆盖不完整的情况下保持未知,同时该资源的其他事实被保留。零和非负分数大小会被保留。
resource_key 仍然是脚本对账所使用的精确观测身份。捕获比较按 URL、来源、类型和 MIME 类型对资源进行分组,然后比较组内的已知大小。如果匹配的组包含未知大小,比较会报告未知,而不是将观测视为资源添加或移除;完整的清单覆盖仍然可以确定整个组的缺失。
CDP 发现有一个 10 秒的响应截止时间。HTTP 发现文档使用 8 MiB 预算。浏览器套接字发现(Browser.getVersion、Target.getTargets)使用 64 MiB 协议消息预算。预算和发现截止时间均没有运行时覆盖。list_browser_targets 不接受 command_timeout_ms:HTTP 发现和浏览器套接字发现(Browser.getVersion、Target.getTargets)保持在该固定截止时间上,并且套接字在没有后续命令的情况下关闭。其他 CDP 工具对每次 WebSocket 握手和命令响应使用 command_timeout_ms(默认 20000),与调用者选择的观测窗口、发现过程以及 5000 ms 清理宽限期分开。浏览器级套接字的握手和随后的 Target.attachToTarget 各自获得该完整截止时间;它们不共享同一个预算。停滞的握手或命令仅在操作接受时报告 provider_timeout 并提及 command_timeout_ms;调用者取消仍报告取消。WebSocket 消息仍受 64 MiB 限制 的约束,该限制没有运行时覆盖。REA 不施加消息数或待处理命令配额。取消时,它只关闭自己的 WebSocket,并在终止前最多等待一秒钟。格式错误的主动事件和对待处理命令的格式错误回复会使连接中毒,导致后续命令失败关闭。相关回复的会话 ID 必须与命令所选会话匹配。可选方法仅在浏览器以未知方法拒绝时才不可用;其他命令拒绝保留其报告的错误。
网络和控制台覆盖仅在 REA 附加并启用相关 CDP 域之后才开始。prior_activity_available 始终为 false;这些数组中的缺失不是某个事件从未发生的证据。脚本则不同:页面在 REA 附加之前解析的脚本仍会在 scripts 下报告。因此,在附加之前加载的页面可以列出其脚本,而 network.requests 缺少获取这些脚本的请求。如果 CDP 在没有提供重定向元数据的情况下重用请求 ID,REA 会保留前一个观测,并将网络覆盖标记为不完整。
检查不会获取源码映射。包分析仅在选择了 fetch_source_maps 时获取它们,并执行精确来源重定向检查,且不附带凭据、Cookie 或 referrer。每次获取操作使用 source_map_fetch_timeout_ms(默认 30000)以及跨重定向的 64 MiB 聚合流式响应预算。字节预算没有运行时覆盖。获取超限是条目限制,而不是抛出的分析超时。截止时间或字节限制失败仍然显式不可用,并使包完整性变为部分。源码映射解码还将原始解析身份限制为 64 MiB,将聚合内联证据限制为 32 MiB。失败的映射会在其可容纳时保留失败上下文;如果某个上下文无法容纳,收集会停止,并返回完整请求计数、已处理计数以及显式的未知结果限制。保留的映射和原始源会以内联方式返回。结构化解码器边界请参阅 source-location limits。带有 .ts、.tsx、.mts 或 .cts 后缀的原始源工件带有 text/typescript;其他源名称保留 text/javascript。
当选择获取时,源码映射的 excluded 事实会保留捕获账本中在下载前被拒绝的声明的原因和计数。不会保留或获取任何不允许的 URL 详细信息。requested 和 processed 统计被允许的获取请求;排除项单独计数。被排除的声明会使集合不可用,或者在保留了映射时使其部分不可用。没有声明的空集合保持为 not_requested。
源码映射条目将脚本的 declared_url 与观测到的 effective_url 分开保留。成功的映射使用后者作为其源解析基础。失败的获取会保留在批准的来源范围内观测到的最后一个响应 URL;当没有观测到响应时,effective_url 为 null。查询参数会被保留,两个 URL 都计入内联证据预算。当前获取会发出字符串或 null;历史观测可能会省略 effective_url,而不会改变其存储内容或证据身份。观测到的 URL 必须先能容纳,之后才会读取其响应正文。如果无法容纳,其余映射结果将显式未知;失败的取消会保留其清理上下文和资源约束。在 ECMA-426 下,解码后的映射越过下一节起始位置的索引映射是无效的,而不是带有被裁剪映射行的完整映射。获取收集和源追踪共享此验证。
非目标与威胁模型¶
浏览器提供方刻意不暴露通用 CDP 命令、Runtime.evaluate、WebMCP 调用、导航、输入、下载、页面关闭或浏览器关闭。截图捕获是唯一的像素接口,并且仅在请求时返回图像。REA 会禁用其启用的域、分离目标会话,并且只关闭自己的 WebSocket。
如果关闭 REA 的 socket 也失败,则发现和附加错误仍然作为主要错误。清理失败会与原始命令失败一同报告;它不能取代操作诊断。
此功能并非浏览器沙箱或网络隔离机制。被附加的页面和浏览器继续以现有权限运行,并且可以独立于 REA 发起外部请求。CDP 可对所选浏览器配置文件提供深度访问,因此请使用专用配置文件,仅包含你打算检查的来源,并将同一用户的其他进程视为该边界之外。
响应元数据会将 Referrer-Policy 回退列表规范化为其最后一个可识别的非空策略,包括混合大小写的 Token。未知的策略名称会被跳过;格式错误的 Token 语法以及不包含可识别策略的列表保持为 null。这报告的是响应声明的策略,而非文档的有效策略或推断出的浏览器默认策略。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 rea2/rea