Ubuntu服务器Puppeteer转大HTML为PDF时出现打印失败协议错误
问题:Ubuntu服务器(Docker环境)下Puppeteer转换大HTML为PDF报错「Protocol error (Page.printToPDF): Printing failed」
本地Windows环境可正常将大体积HTML文件通过Puppeteer转换为PDF,但部署到Ubuntu服务器的Docker环境时,出现「Protocol error (Page.printToPDF): Printing failed」错误。已尝试将headless设为true和new,均无效果。
相关代码片段
import * as puppeteer from 'puppeteer'; await puppeteer.launch({ headless: true, executablePath: '/usr/bin/google-chrome', args: ['--no-sandbox'] }); const page = await browser.newPage(); await page.setContent(renderedTemplate); // 传入HTML内容 const css = ` @media print { .new-page { page-break-before: always; } } `; await page.addStyleTag({ content: css }); const pdfBuffer = await page.pdf({ format: 'A4', printBackground: true, displayHeaderFooter: true, headerTemplate: headerTemplate, footerTemplate: footerTemplate, margin: { top: '100px', bottom: '100px', left: '15px', right: '15px' }, timeout: 600000, }); // PDF转换 await browser.close(); // 关闭浏览器连接
Docker中Chrome安装脚本
RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \ && apt-get install -y ./google-chrome-stable_current_amd64.deb \ && rm google-chrome-stable_current_amd64.deb \ && echo "Chrome: " && google-chrome --version
解决方向
1. 补全Chrome系统依赖
Docker中安装的Chrome可能缺少基础依赖,导致PDF打印功能异常。在安装Chrome的脚本后补充以下命令:
RUN apt-get install -y fonts-liberation libasound2 libatk-bridge2.0-0 libnss3 libx11-xcb1 libxcb-dri3-0 libxcomposite1 libxcursor1 libxdamage1 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6
2. 优化Puppeteer启动参数
添加针对Docker环境的参数,避免资源不足或渲染阻塞:
await puppeteer.launch({ headless: 'new', executablePath: '/usr/bin/google-chrome', args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', // 解决/dev/shm空间限制问题 '--disable-gpu', '--disable-extensions', '--disable-background-timer-throttling' ] });
3. 确保页面完全渲染
大体积HTML需要等待资源加载完成再执行转换,修改setContent的等待策略:
await page.setContent(renderedTemplate, { waitUntil: 'networkidle0' });
同时可尝试增加Docker容器的内存分配,比如启动容器时添加-m 4g参数。
4. 排查HTML内容异常
大文件转换失败可能和内容中的异常元素有关:
- 确保所有外部图片、字体资源已内嵌或能正常访问
- 移除复杂动画、未加载的外部脚本等可能阻塞渲染的元素
- 用简化版HTML测试转换,逐步定位问题点
5. 匹配Puppeteer与Chrome版本
版本不兼容会导致协议错误,可直接使用Puppeteer自带的Chrome(无需手动安装):
await puppeteer.launch({ headless: 'new', args: ['--no-sandbox'] });
若必须手动安装Chrome,需确保版本与当前Puppeteer要求一致。
内容的提问来源于stack exchange,提问作者Sarathkumar Vulchi
相关产品推荐
相关产品推荐

