如何在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); }); } });
关键说明
- 精准过滤请求:通过URL包含的
firestore.googleapis.com来定位目标请求,避免处理其他无关的XHR请求。 - 缓冲区累积与解析:因为每一段数据可能不完整,所以用缓冲区攒数据,每次收到新chunk后检查是否能凑出完整的消息(通过长度标记判断)。
- 实时处理逻辑:解析出完整消息后,你可以直接针对
targetChange这类关键数据做实时展示或存储,不用等整个请求结束。
这样就能和浏览器开发者工具里看到的一样,实时拿到每一条Firestore推送的更新消息了!
备注:内容来源于stack exchange,提问作者EdE
相关产品推荐
相关产品推荐

