我似乎找不到有关此用例的任何文档。我希望从我无法控制的来源中截取SSE消息,因此无法将其更改为服务器发送的事件。
答案 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();
});