Puppeteer在Linux与Windows生成PDF结果不一致问题咨询
解决WSL环境下Puppeteer生成PDF丢失Canvas DataURL图表的问题
我之前在WSL里用Puppeteer生成PDF时也碰到过一模一样的问题——Windows下正常显示的Canvas图表,到了Linux(WSL)环境就凭空消失了。结合你的代码,分享几个亲测有效的解决思路:
1. 确保Canvas完全渲染完成再生成PDF
你当前用了networkidle0等待网络请求结束,但Canvas图表是客户端动态绘制的,网络空闲不代表Canvas已经绘制完毕。可以添加一段等待逻辑,检测Canvas是否有实际内容:
async function printPDF() { const browser = await puppeteer.launch({headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox']}); const page = await browser.newPage(); await page.goto('http://localhost:8080/new', {waitUntil: 'networkidle0'}); // 新增:等待Canvas绘制完成(检测左上角像素是否有非透明内容) await page.waitForFunction(() => { const canvas = document.querySelector('canvas'); if (!canvas) return false; const ctx = canvas.getContext('2d'); const [r, g, b, a] = ctx.getImageData(0, 0, 1, 1).data; return r + g + b + a !== 0; }, { timeout: 10000 }); // 设置10秒超时,避免无限等待 const pdf = await page.pdf({ format: 'A4', printBackground: true, path: __dirname+'/s.pdf' }); await browser.close(); return pdf }
2. 调整Puppeteer启动参数适配WSL环境
WSL的系统环境和原生Linux有差异,默认的Chromium启动参数可能导致渲染异常。试试更新这些参数:
const browser = await puppeteer.launch({ headless: 'new', // 改用新版无头模式,兼容性更好 args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', // 解决WSL共享内存不足的问题 '--disable-gpu', // WSL通常没有GPU硬件加速,禁用避免报错 '--enable-features=NetworkService,NetworkServiceInProcess' ] });
3. 修复Canvas DataURL的渲染逻辑
有时候WSL下的Chromium对DataURL的解析有问题,可以在页面里重新触发Canvas的渲染:
async function printPDF() { const browser = await puppeteer.launch({headless: 'new', args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage']}); const page = await browser.newPage(); await page.goto('http://localhost:8080/new', {waitUntil: 'networkidle0'}); // 新增:重新渲染Canvas内容 await page.evaluate(() => { document.querySelectorAll('canvas').forEach(canvas => { const dataUrl = canvas.toDataURL(); const tempImg = new Image(); tempImg.onload = () => { const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(tempImg, 0, 0); }; tempImg.src = dataUrl; }); }); // 等待重新渲染完成 await page.waitForTimeout(1000); const pdf = await page.pdf({ format: 'A4', printBackground: true, path: __dirname+'/s.pdf' }); await browser.close(); return pdf }
4. 安装WSL下Chromium依赖
如果以上方法都无效,可能是WSL缺少Chromium运行必需的系统库。执行以下命令安装依赖:
sudo apt-get update && sudo apt-get install -y libnss3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxrandr2 libgbm1 libgtk-3-0 libasound2
建议按顺序尝试这些方案,一般前两个就能解决问题。
内容的提问来源于stack exchange,提问作者loliallen
相关产品推荐
相关产品推荐

