如何在Puppeteer中拦截服务器发送的事件消息

时间:2019-09-17 19:28:50

标签: puppeteer

我似乎找不到有关此用例的任何文档。我希望从我无法控制的来源中截取SSE消息,因此无法将其更改为服务器发送的事件。

1 个答案:

答案 0 :(得分:1)

Puppeteer没有等待SSE的本地事件,但是您可以使用Chrome DevTools协议来执行此操作。参考为here,示例代码为:

  // some code

  // after you have access to "Page":
  const cdp = await page.target().createCDPSession();
  await cdp.send('Network.enable');
  await cdp.send('Page.enable');
  cdp.on('Network.eventSourceMessageReceived', ({ requestId, timestamp, eventName, eventId, data }) => console.log(requestId, timestamp, eventName, eventId, data));

  // now you can navigate to the page you are testing:
  await page.goto('<url with SSE>');

编辑: 我准备了一个完整的示例,其中有一个expressjs扮演SSE服务器角色,还有一个使用事件的伪造者客户端:

const puppeteer = require('puppeteer');
const express = require('express');
const app = express();


app.get('/', (req, res) => {
  res.send(`
    <!DOCTYPE html>
    <body>
      <script>
        var sseSource = new EventSource('/event-stream');
        sseSource.addEventListener('MyEvent', (e) => {
          console.log('[Page] Event Type:', e.type, '| Event Data:', e.data);
        });
      </script>
    </body>
    </html>
  `);
});

app.get('/event-stream', (req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  });
  res.write('\n');
  const intervalId = setInterval(() => {
    res.write(`event: MyEvent\n`);
    res.write(`data: Test Message received at ${Date.now()}\n\n`);
  }, 1000);
  req.on('close', () => clearInterval(intervalId));
});

const server = app.listen(8080, async () => {
  const browser = await puppeteer.launch();

  const page = await browser.newPage();
  await page.setDefaultTimeout(0);

  const cdp = await page.target().createCDPSession();
  await cdp.send('Network.enable');
  await cdp.send('Page.enable');
  cdp.on('Network.eventSourceMessageReceived', ({ eventName, data }) => console.log(`[Node] Event Type: ${eventName} | Event Data: ${data}\n`));
  page.on('console', (msg) => console.log(msg.text()));
  await page.goto('http://localhost:8080/');
  await page.waitFor(300000); // 5 minutes
  await page.close();
  await browser.close();
  server.close();
});