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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 12:22:52