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

如何在Puppeteer中实时获取Firestore请求的分段响应数据?

如何在Puppeteer中实时获取Firestore请求的分段响应数据?

嘿,这个问题我之前做实时数据抓取时也碰到过!你现在用的response.text()会等待整个响应完全下载完成才返回内容,但Firestore的实时更新请求用的是分块传输编码(Chunked Transfer Encoding),数据是一段一段推过来的,所以得换个方式监听数据流才行。

核心问题分析

你看到的那些带数字前缀的消息,是Firestore流式响应的标准格式——数字代表后续消息内容的字节长度,跟着就是实际的JSON数据块。response.text()会把所有分块攒齐后再返回,自然没法实时拿到每一段更新。

解决方案:监听响应的可读流

我们可以直接获取响应的可读流,逐块接收数据,再按Firestore的格式解析出每一条完整消息。具体代码如下:

page.on('response', async (response) => {
  // 精准过滤Firestore的XHR请求(可以根据你的实际URL调整判断条件)
  const isFirestoreRequest = 
    response.request().resourceType() === 'xhr' && 
    response.url().includes('firestore.googleapis.com');

  if (isFirestoreRequest) {
    console.log('开始监听Firestore流式响应:', response.url());
    let buffer = ''; // 用来累积未处理的分段数据

    // 获取响应的可读流
    const stream = await response.body();

    // 监听每一段数据的到来
    stream.on('data', (chunk) => {
      buffer += chunk.toString('utf8');
      
      // 循环处理缓冲区里的完整消息
      while (true) {
        // 找到长度标记后的换行符,分割长度和消息内容
        const newlineIndex = buffer.indexOf('\n');
        if (newlineIndex === -1) break; // 没有完整的长度标记,等待下一个chunk

        const lengthStr = buffer.slice(0, newlineIndex);
        const contentLength = parseInt(lengthStr, 10);
        if (isNaN(contentLength)) {
          // 格式异常,跳过当前无效片段
          buffer = buffer.slice(newlineIndex + 1);
          continue;
        }

        // 检查缓冲区是否有足够的内容来提取完整消息
        const messageStart = newlineIndex + 1;
        const messageEnd = messageStart + contentLength;
        if (buffer.length < messageEnd) break; // 内容不足,等待后续chunk

        // 提取并解析完整消息
        const messageContent = buffer.slice(messageStart, messageEnd);
        try {
          const messageData = JSON.parse(messageContent);
          console.log('实时收到Firestore消息:', messageData);
          
          // 这里可以针对你需要的targetChange做实时处理
          if (messageData[0]?.[1]?.targetChange) {
            console.log('实时更新数据:', messageData[0][1].targetChange);
          }
        } catch (err) {
          console.error('消息解析失败:', err);
        }

        // 移除已处理的内容,更新缓冲区
        buffer = buffer.slice(messageEnd);
      }
    });

    // 监听流结束事件
    stream.on('end', () => {
      console.log('Firestore响应流结束');
    });

    // 处理流读取错误
    stream.on('error', (err) => {
      console.error('流式响应读取出错:', err);
    });
  }
});

关键说明

  1. 精准过滤请求:通过URL包含的firestore.googleapis.com来定位目标请求,避免处理其他无关的XHR请求。
  2. 缓冲区累积与解析:因为每一段数据可能不完整,所以用缓冲区攒数据,每次收到新chunk后检查是否能凑出完整的消息(通过长度标记判断)。
  3. 实时处理逻辑:解析出完整消息后,你可以直接针对targetChange这类关键数据做实时展示或存储,不用等整个请求结束。

这样就能和浏览器开发者工具里看到的一样,实时拿到每一条Firestore推送的更新消息了!

备注:内容来源于stack exchange,提问作者EdE

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 09:47:59