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

AWS上用Puppeteer的page.pdf()报错:ReadableStream未定义

问题:Node 18 + Puppeteer 22.3.0 AWS生产环境PDF下载报错ReferenceError: ReadableStream is not defined

背景

  • 本地Node 18环境运行Puppeteer 22.3.0实现的PDF下载功能完全正常
  • 部署到AWS生产环境后,调用PDF下载API返回ReferenceError: ReadableStream is not defined错误

错误栈

error:  ReferenceError: ReadableStream is not defined
at getReadableFromProtocolStream (/var/www/max-scaffolds/backend/node_modules/puppeteer-core/lib/cjs/puppeteer/common/util.js:241:5)
at CdpPage.createPDFStream (/var/www/max-scaffolds/backend/node_modules/puppeteer-core/lib/cjs/puppeteer/cdp/Page.js:845:66)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async CdpPage.pdf (/var/www/max-scaffolds/backend/node_modules/puppeteer-core/lib/cjs/puppeteer/cdp/Page.js:849:26)

相关代码

public getReportPdf = async(req: Request, res: Response) =>{
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  try {
    const {
      reportId
    } = req.params;
    const reportData = await this.reportRepo.getJobAndTemplateWithReport(reportId);
    const htmlData = await ejs.renderFile('src/helper/templates/report.ejs', {
      record: reportData[0],
      reportOverview: REPORT_OVERVIEW
    });
    const image = await getBase64Image('https://maxscaffold-front-stg.taskgrids.com/assets/images/Max-Builders-Default.png') // Need to pass here companyLogo url
    await page.setContent(htmlData);
    const pdfBuffer = await page.pdf({
      displayHeaderFooter: true,
      headerTemplate: ` < div style = "font-size: 10px; display: flex; justify-content: center; align-items: center; margin-left: 300px" > <div > Powered by < /div>
        <img style="height: 50px; width: auto; margin-left: 5px" src="data:image/png;
      base64,
      ${image}
      "/>
        </div>`,
        format: 'A4',
        printBackground: true,
        preferCSSPageSize: true,
        scale: 0.8,
        margin: {
          top: '100px',
          bottom:'50px'
        }
      });
      await page.close();
      await browser.close();

      const savepath = `./${STORAGE_BUCKET.DEFAULT}/${reportId}_report.pdf`;

      fs.writeFile(savepath, pdfBuffer, (err) => {
        if (err) {
          console.log('err', err);
        }
      });
      setTimeout(() => {
        fs.promises.unlink(savepath);
      }, 25000);

  
      const data = process.env.NODE_URL + `api/images/${reportId}_report.pdf`;
       return generalResponse(req, res,data, successMessage.REPORT_DISPLAY_SUCCESS, true, responseFlag.SUCCESS);
    } catch (error) {
      await page.close();
      await browser.close();
      return generalResponse(req, res, error, errorMessage.SOMETHING_WRONG, false, responseFlag.ERROR);
    }
  };

解决方案

1. 显式全局挂载ReadableStream

Puppeteer 22+版本依赖全局的ReadableStream对象,但部分AWS运行环境(如特定容器镜像、Lambda自定义运行时)中该对象未被默认挂载。在代码入口或该API文件顶部添加以下代码:

如果是ES模块(import语法):

import { ReadableStream } from 'stream/web';
globalThis.ReadableStream = ReadableStream;

如果是CommonJS模块(require语法):

const { ReadableStream } = require('stream/web');
global.ReadableStream = ReadableStream;

2. 验证AWS环境Node版本一致性

  • 确认AWS生产环境使用的确实是Node.js 18.x版本,避免容器镜像或运行时配置错误导致版本不符
  • 若使用AWS Lambda,检查函数配置的运行时是否为Node.js 18.x,同时排查是否有自定义环境变量修改了全局对象

3. 降级Puppeteer版本(临时应急方案)

若上述方法无效,可临时降级到Puppeteer 21.x版本,该版本对Node 18的兼容性更稳定,不会强制依赖全局的ReadableStream:

npm install puppeteer@21.11.0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 22:53:20