You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Puppeteer在Lambda生成PDF时出现浏览器断开导航失败错误

Puppeteer在Lambda中生成带图片的PDF时触发浏览器断开错误

我们基于Puppeteer开发了一个Lambda函数,用于将HTML内容转换为PDF文件,依赖包为chrome-aws-lambda@8.0.2和puppeteer-core@8.0.0。在QA环境中,当HTML不含图片时PDF生成正常,但只要包含图片(无论是background-image还是<img>标签),就会触发Puppeteer错误。目前已将Lambda的临时存储和内存调至最大值10240MB,问题仍未解决。

依赖安装命令:

npm install chrome-aws-lambda@8.0.2 puppeteer-core@8.0.0 --save-prod

异常信息

{
   "errorMessage": "Navigation failed because browser has disconnected!",
   "stack": [
       "Error: Navigation failed because browser has disconnected!",
       "    at /var/task/node_modules/puppeteer-core/lib/cjs/puppeteer/common/LifecycleWatcher.js:51:147",
       "    at /var/task/node_modules/puppeteer-core/lib/cjs/vendor/mitt/src/index.js:51:62",
       "    at Array.map (<anonymous>)",
       "    at Object.emit (/var/task/node_modules/puppeteer-core/lib/cjs/vendor/mitt/src/index.js:51:43)",
       "    at CDPSession.emit (/var/task/node_modules/puppeteer-core/lib/cjs/puppeteer/common/EventEmitter.js:72:22)",
       "    at CDPSession._onClosed (/var/task/node_modules/puppeteer-core/lib/cjs/puppeteer/common/Connection.js:247:14)",
       "    at Connection._onClose (/var/task/node_modules/puppeteer-core/lib/cjs/puppeteer/common/Connection.js:128:21)",
       "    at WebSocket.<anonymous> (/var/task/node_modules/puppeteer-core/lib/cjs/puppeteer/node/NodeWebSocketTransport.js:17:30)",
       "    at WebSocket.onClose (/var/task/node_modules/ws/lib/event-target.js:124:16)",
       "    at WebSocket.emit (events.js:400:28)"
   ]
}

代码片段

async function getBrowser() {
  if (puppeteer) {
    return await puppeteer.launch({ headless: true });
  }
  // if running in lambda return chromium lambda
  if (chromium) {
    return await chromium.puppeteer.launch({
      args: chromium.args,
      defaultViewport: chromium.defaultViewport,
      executablePath: await chromium.executablePath,
      headless: chromium.headless,
      ignoreHTTPSErrors: true
    });
  }
}

export const html2pdf = async (html = '', url = '', format = 'Legal') => {
  let myBrowser = await getBrowser();
  const page = await myBrowser.newPage();
  const loaded = page.waitForNavigation({
    waitUntil: 'load'
  });

  if (html) {
    await page.setContent(html, { waitUntil: 'networkidle0' });
  } else if (url) {
    await page.goto(url, { waitUntil: 'networkidle0' });
  }
  // await page.setViewport({ isMobile: true, width: 375, height: 667 });
  await loaded;

  const pdf = await page.pdf({ format: format });
  await page.close();
  await myBrowser.close();
  return pdf;
};

解决方案与调试建议

1. 修复waitForNavigation的错误使用

代码中提前声明loaded = page.waitForNavigation(...),但page.setContent或page.goto本身已包含导航等待逻辑,再单独await loaded会导致逻辑冲突——导航已完成后waitForNavigation会超时,最终引发浏览器连接断开。

修改后的代码:

export const html2pdf = async (html = '', url = '', format = 'Legal') => {
  let myBrowser = await getBrowser();
  const page = await myBrowser.newPage();

  if (html) {
    await page.setContent(html, { waitUntil: 'networkidle0' });
  } else if (url) {
    await page.goto(url, { waitUntil: 'networkidle0' });
  }

  const pdf = await page.pdf({ format: format });
  await page.close();
  await myBrowser.close();
  return pdf;
};

2. 优化Chromium启动参数适配Lambda环境

在getBrowser的Chromium配置中补充关键参数,避免资源耗尽或连接异常:

return await chromium.puppeteer.launch({
  args: [
    ...chromium.args,
    '--disable-dev-shm-usage', // 禁用Lambda空间有限的/dev/shm
    '--disable-gpu',
    '--single-process', // 单进程模式减少资源占用
    '--no-zygote' // 避免zygote进程兼容性问题
  ],
  defaultViewport: chromium.defaultViewport,
  executablePath: await chromium.executablePath,
  headless: chromium.headless,
  ignoreHTTPSErrors: true,
  timeout: 0 // 取消启动超时限制,适配大资源加载场景
});

3. 处理图片加载超时与异常

图片加载慢或失败可能导致页面挂起,进而断开浏览器连接:

  • 给page.setContent/page.goto增加超时时间:
    await page.setContent(html, { waitUntil: 'networkidle0', timeout: 30000 }); // 30秒超时
    
  • 监听页面错误与请求失败事件,定位具体图片问题:
    page.on('error', err => console.error('页面错误:', err));
    page.on('requestfailed', req => console.error('请求失败:', req.url(), req.failure()));
    

4. 升级依赖版本

当前使用的chrome-aws-lambda@8.0.2和puppeteer-core@8.0.0版本较旧,存在已知的Lambda适配问题。建议升级到兼容的稳定版本(注意两者大版本需一致):

npm install chrome-aws-lambda@10.1.0 puppeteer-core@10.1.0 --save-prod

5. 验证Lambda执行环境配置

  • 确认Lambda运行时为Node.js 14.x及以上,旧版本可能不兼容新版Chromium
  • 将Lambda执行时间限制设为最大值5分钟,避免大图片加载时超时

内容的提问来源于stack exchange,提问作者codeflinger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 23:53:22