我有一个node js应用程序,它创建动态内容,我希望用户下载这些内容。
static async downloadPDF(res, html, filename) {
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch({
headless: true
});
const page = await browser.newPage()
await page.setContent(html, {
waitUntil: 'domcontentloaded'
})
const pdfBuffer = await page.pdf({
format: 'A4'
});
res.set("Content-Disposition", "attachment;filename=" + filename + ".pdf");
res.setHeader("Content-Type", "application/pdf");
res.send(pdfBuffer);
await browser.close()
}
由于创建一个大小约100KB的pdf文件大约需要10秒,有没有一种方法可以加快整个过程?我在某处读到,我可以启动无头浏览器一次,然后我将只创建一个新的页面,而不是每次我请求文件时都启动一个浏览器。我找不出做这件事的正确方法。
您可以将page
创建移动到一个util中,并将其提升以重用它。
const puppeteer = require('puppeteer');
let page;
const getPage = async () => {
if (page) return page;
const browser = await puppeteer.launch({
headless: true,
});
page = await browser.newPage();
return page;
};
.
const getPage = require('./getPage');
static async downloadPDF(res, html, filename) {
const page = await getPage()
}
是的,没有理由每次都启动浏览器。您可以将puppeter设置为调用新的url并获取内容。没有每次发射,会更快。
如何实施?将您的功能简化为三个步骤:
>
创建浏览器实例。不管无头与否。如果您在X环境中运行应用程序,您可以启动一个窗口,以查看您木偶手在做什么
创建一个函数代码,它将在循环中完成主要任务。
block完成后,调用await page.goto(url)
(其中“page”是browser.newpage()
)的实例)并再次运行函数。
这是函数样式代码中可能的解决方案之一:
>
创建实例:
const browser=await Puppeteer.Launch({“headless”:false});常量page=await Browser.newPage();Page.SetViewPort({“width”:1280,“height”:1024});
我将它放在实时异步函数中,如(async()=>{})();
在我的例子中,mongo db中有一组URL,在得到它之后,我运行了一个循环:
for( const entrie of entries)
{
const url = entrie[1];
const id = entrie[0];
await get_aplicants_data(page,url,id,collection);
}
在get_aplicants_data()中,我根据加载的页面实现了一个逻辑:
await page.goto(url);//转到url
....prcess页数据的代码
您还可以循环加载url,然后放入您的逻辑
(希望我给了你一些帮助)