说说 page.on('response',fn)

说说 page.on('response',fn)

page.waitForResponse 类似,page.on('response', fn) 同样可以用于监听和等待网络请求的响应,两者的执行环境均为 Node.js,且底层都基于对 Network.responseReceived 事件的监听。然而,它们在特性、适用场景和实现机制上都存在着显著差异。

特性 page.waitForResponse page.on('response',fn)
监听机制 一次性处理器 持久监听器
资源清理 自动清理匹配的处理器 需要手动移除监听器
使用模式 Promise-based EventEmitter-based
返回值 Promise(单个Response) 无返回值
适用场景 等待一个符合条件的响应 & 短时间内可以返回满足要求的响应 监控所有网络活动 或 等待一个长时间才能返回的响应
错误处理 内置超时机制 需要自行实现

底层原理剖析

从设置 page.on('response', fn) 进行监听到捕获想要的 response,实际上会经历以下流程:

  1. Puppeteer 在 launch 浏览器时即创建了与 Chromium 之间的 WebSocket 通信通道;

  2. 当 Nodejs 层设置 page.on('response', fn) 方法时,即从 Puppeteer 通过 WebSocket 向 Chromium 发送一条 Network.enable 消息以启用网络监控,并在 Puppeteer 层的内部事件发射器(Event Emitter)上为 response 事件注册了一个监听器(也就是将你的回调函数存起来,等待后续触发);

    1. Network.enableCDP (Chrome DevTools Protocol) 中的一个命令,它的主要作用是:

      • 启用网络域监控:告诉 Chromium 开始收集和发送网络相关的所有事件;
      • 开启网络流量追踪:激活浏览器内部的网络监控功能;
    2. 实际上,为了避免不必要的 CDP 命令调用,并不是每次设置 page.on('response', fn) 时都会发送 Network.enable 消息,而是先由 Puppeteer 确认是否已经开启网络监控,只有在确认未开启时,才会发送消息,否则就不发送了;

  3. 当 Chromium 内核接收到原始的网络数据(包含 HTTP 状态码、头部、响应体后)后,通过 WebSocket 向 Puppeteer 发送"携带了原始的网络数据(不包含响应体 )的 Network.responseReceived CDP 事件";

  4. 由 Puppeteer 接收到网络的原始数据后封装成一个统一的、易于使用的 HttpResponse 对象,这个对象包含了像 status()、url()、ok() 等方便开发者使用的方法;

  5. 然后,再由 Puppeteer 将这个对象作为参数,触发第二步中注册好的回调函数:page.emit('response', fn)

关于响应体未在 Network.responseReceived CDP 事件中传递的说明

首先,这是为了性能考虑。如果每个响应都直接传输完整的响应体(特别是对于大文件),会占用大量的内存和带宽。因此,Chromium 默认只发送轻量级的元数据;

其次,Puppeteer 接收到 Network.responseReceived 事件后,会封装一个 Response 对象。此时,这个对象里还没有响应体数据。只有当你在 回调函数或 Nodejs 层 显式调用了 response.buffer()(或 response.json()、response.text())方法时,Puppeteer 才会:

  1. 向浏览器发送一个 Network.getResponseBody 的 CDP 命令;
  2. 浏览器接收到命令后,将完整的响应体数据通过 WebSocket 发送给 Puppeteer;
  3. Puppeteer 将接收到的数据填充到 Response 对象中,并返回给回调函数或 Nodejs 层
相关推荐
用户059540174465 小时前
LLM对话记忆测试踩坑实录:手工回归30分钟,自动化后2分钟发现3个隐藏Bug
前端·css
Ashley的成长之路7 小时前
前端性能优化实战手册·第2篇:资源加载策略全解
前端·性能优化·资源加载·http/3·性能优化实战·资源加载优化
浅水壁虎7 小时前
vue基础(第二章 )
前端·javascript·vue.js
界面开发小八哥7 小时前
界面控件DevExtreme v26.1新版亮点——支持Angular 22
前端·javascript·angular.js·devexpress·ui开发·devextreme
Getflare7 小时前
前端 + UI 设计 + AI:这不是三个工种,是一个新三角能力模型(附自检清单)
前端·人工智能·ui
oil欧哟7 小时前
我做了一个 Vibe Coding 术语学习站:VibeHub
前端·ai·agent·独立开发·vibe coding
审小匠OpenCPAi8 小时前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计
Revolution618 小时前
一个公共表格组件,是怎么一步步失控的
前端·前端工程化
腻害兔8 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:CRM 客户关系模块深度解析——从线索到回款,一套完整的 B2B 销售闭环是怎么搭的?
java·前端·javascript·vue.js·产品经理·ai编程