You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeError: client.on is not a function 报错排查与修复方法

错误原因

TypeError: client.on is not a function 本质是你调用on()的client对象不是支持事件监听的合法CDP会话实例,具体触发场景:

  • 代码里取的d._client是Puppeteer/Playwright的内部私有属性,下划线开头的属性没有对外兼容性承诺,不同版本里可能指向无事件方法的普通内部对象、undefined,或者被代理过的只读对象,本身就不支持直接绑定事件
  • 你监听的Network.webSocketFrameSent是Chrome DevTools Protocol的协议层事件,只能绑定在官方API创建的CDPSession实例上,不能直接绑在页面对象的内部属性上
  • 新版本的Puppeteer/Playwright已经移除了页面对象挂载的_client属性的事件能力,外部读取到的_client没有继承EventEmitter原型,自然不存在on方法。
修复方案
  • 不要读取私有_client属性,改用官方公开API创建合法CDP会话:
    • Puppeteer环境:const client = await DiscordPage.target().createCDPSession()
    • Playwright环境:const client = await DiscordPage.context().newCDPSession(DiscordPage)
  • 绑定网络类事件前,必须先执行await client.send('Network.enable')开启CDP网络域事件推送,否则绑定后也收不到WebSocket帧数据
  • 给回调里的字段加可选链判断,避免字段不存在时抛出额外解析错误。
修正后代码
const DiscordPage = d;
await fill_discord(DiscordPage, username, password, email);

let client;
// 自动适配Puppeteer、Playwright两种运行环境
if (DiscordPage.target) {
  client = await DiscordPage.target().createCDPSession();
} else {
  client = await DiscordPage.context().newCDPSession(DiscordPage);
}

let token;
// 先开启网络域监听
await client.send('Network.enable');

client.on('Network.webSocketFrameSent', ({requestId, timestamp, response}) => {
  try {
    if (!response?.payloadData) return;
    const json = JSON.parse(response.payloadData);
    if(!token && json?.d?.token){
      token = json.d.token;
      write_log(true, `Token: ${token}`);
    }
  } catch(e) {
    // 非JSON格式帧直接忽略
  }
})
await break_captcha(DiscordPage);
注意事项
  • 不要在业务代码里直接调用库的下划线开头内部属性,这类属性会随版本迭代随意调整结构、移除方法,没有任何兼容性保障
  • CDP事件是异步触发的,如果需要在break_captcha执行后读取token值,需要额外加Promise等待逻辑,直接同步读取大概率拿到undefined。

内容的提问来源于stack exchange,提问作者retrocheese

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 18:06:18