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

React组件通过Puppeteer生成PDF为空问题求助

React页面生成空PDF问题排查

场景描述

实现流程:未授权用户进入「申请项目报告」页面提交申请,管理员审批后,NestJS服务器调用Puppeteer容器生成React页面的PDF,再通过Nodemailer发送邮件。当前问题:传入谷歌URL时PDF生成正常,但传入React应用URL时返回空PDF,响应数据显示为data: <Buffer >。

相关代码

NestJS服务器代码

await axios
  .get(`${PUPPETEER_APP_URL}/pdf`, {
    responseType: 'arraybuffer',
    params: { url: programUrl }
  })

Puppeteer应用代码

路由

app.get('/pdf', async (req, res) => {
  const url = req.query.url
  const result = await generatePdf(`${CLOUD_APP_URL}/${url}`)
  res.contentType('application/pdf');
  res.send(result);
});

服务

const puppeteer = require('puppeteer');

const generatePdf = async (payload) => {
  try {
    const browser = await puppeteer.launch({
      headless: true,
      args: ['--no-sandbox', '--disable-setuid-sandbox']
    });
  
    const page = await browser.newPage();
    await page.goto(payload, {
      waitUntil: ['domcontentloaded', 'networkidle0', 'load']
    })
    await page.emulateMediaType('screen')
    const pdf = await page.pdf();
    await browser.close();
  
    return pdf;
  } catch (error) {
    console.log('GENERATE PDF ERROR :>> ', error);
  }
};

module.exports = generatePdf;

可能的原因及排查步骤

1. React页面异步渲染未完成

虽然设置了waitUntil参数,但React的异步数据请求、组件挂载后的渲染操作可能在domcontentloaded/networkidle0事件之后才完成,导致Puppeteer提前生成PDF。

  • 排查方案:
    • 等待页面中关键渲染元素加载完成:
      // 替换#report-content为页面实际存在的内容容器选择器
      await page.waitForSelector('#report-content', { timeout: 10000 });
      
    • 临时添加固定延迟测试(仅用于验证):
      await page.waitForTimeout(3000); // 等待3秒确保渲染完成
      

2. Puppeteer无权限访问React页面

React页面可能存在权限校验,Puppeteer访问时未携带认证信息(如Token、Cookie),导致页面跳转到登录页或显示空白。

  • 排查方案:
    • 打印页面响应内容,确认实际访问结果:
      page.on('response', async (response) => {
        if (response.url() === payload) {
          console.log('页面响应状态:', response.status());
          console.log('页面响应内容:', await response.text());
        }
      });
      
    • 携带必要的认证信息:
      // 设置认证请求头
      await page.setExtraHTTPHeaders({
        'Authorization': 'Bearer YOUR_AUTH_TOKEN'
      });
      // 或设置Cookie
      await page.setCookie({
        name: 'auth_token',
        value: 'YOUR_TOKEN',
        domain: new URL(payload).hostname
      });
      

3. 网络连通性或URL格式问题

Puppeteer容器可能无法访问React应用的网络地址,或者URL拼接时出现格式错误(如重复斜杠)。

  • 排查方案:
    • 在Puppeteer容器内测试网络连通性:
      curl -v YOUR_REACT_APP_FULL_URL
      
    • 打印拼接后的完整URL,检查格式:
      const fullUrl = `${CLOUD_APP_URL}/${url}`;
      console.log('最终访问URL:', fullUrl);
      

4. Headless模式兼容性问题

新版Puppeteer的headless: true对应「new headless」模式,可能存在渲染兼容性问题。

  • 排查方案:
    • 切换为旧版无头模式测试:
      const browser = await puppeteer.launch({
        headless: 'old',
        args: ['--no-sandbox', '--disable-setuid-sandbox']
      });
      

5. CSS样式导致内容隐藏

页面的CSS属性(如display: none、height: 0)可能导致内容在PDF中无法显示。

  • 排查方案:
    • 生成页面截图,确认实际渲染内容:
      await page.screenshot({ path: 'test-screenshot.png' });
      
    • 检查页面容器元素的样式,确保内容可见且有正确的高度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 03:41:17