我需要为包含约20个iframe并显示一些图表的网页创建PDF。显然,我需要等待所有iframe加载完毕。为此,我尝试了以下操作(摘要):
const browser = await puppeteer.launch({ args: ['--no-sandbox'] })
const page = await browser.newPage()
const navigationPromise = page.waitForNavigation({waitUntil: 'networkidle0'})
await page.goto(url)
await navigationPromise
const pdf = await page.pdf()
await browser.close()
我的理解是,waitUntil: 'networkidle0'
选项应该等待直到500毫秒内完全没有网络流量。但是,iframe并不总是显示,有些是,有些则没有。
我也尝试了networkidle2
,但没有任何改善(这应该适用于长期运行的网络连接,而我们并不这样)。
还有什么其他方法可以确保所有iframe都已加载?
答案 0 :(得分:2)
通常,load
和networkidle*
事件应在框架加载后触发。但是,如果在解析page.waitForNavigation
之后将框架附加到页面上,则可能需要专门侦听要加载的框架。
存在framenavigated
事件,该事件“在将框架导航到新的url时发出”。如果您知道需要收听的帧数,则只需等待所有帧加载完毕,就可以像这样:
const EXPECTED_NUMBER_OF_FRAMES = 5;
await Promise.all([
new Promise(resolve => { // wait until all frames are navigated
let numberOfLoadedFrames = 0;
page.on('framenavigated', () => {
numberOfLoadedFrames += 1;
if (numberOfLoadedFrames === (EXPECTED_NUMBER_OF_FRAMES + 1)) {
resolve();
}
});
}),
page.goto('...')
]);
当达到预期数量时,代码将监听framenavigated
事件调用的数量和resolve
的承诺。请记住,主机也会触发一次framenavigated
事件,因此会触发我的代码中的EXPECTED_NUMBER_OF_FRAMES + 1
。
根据页面的复杂程度,您还可以侦听frameattached
事件的发出数量,这些事件将表示页面中有多少帧。这样,您可以自动检测页面中有多少帧。但是,在这种情况下,您应该首先等待几毫秒,以确保捕获所有帧。