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

Node+Express中使用jsPDF模块报错window未定义致服务崩溃

解决Node.js/Express环境中使用jsPDF导致服务器崩溃的问题

嘿,我一眼就看出问题所在了——jsPDF本来是给浏览器环境设计的,它依赖浏览器里的window全局对象,但Node.js服务器端根本没有这个东西!你贴的报错里提到window.AcroForm,就是最直接的证据,服务器启动时找不到window,直接就崩了。

给你几个靠谱的解决办法,按推荐程度排序:

方案1:用适配Node.js的jsPDF封装包

直接用原生jspdf在服务端肯定踩坑,不过有个专门封装好的jspdf-node,已经帮你处理了环境兼容问题,用起来很省心:

  1. 先把原来的jspdf卸掉:
    npm uninstall jspdf
    
  2. 安装jspdf-node:
    npm install jspdf-node
    
  3. 在server.js里这么用(举个生成PDF返回给客户端的例子):
    const pdf = require('jspdf-node');
    const express = require('express');
    const app = express();
    
    app.get('/get-pdf', async (req, res) => {
      const pdfOptions = {
        format: 'A4',
        content: '<div style="text-align:center;"><h1>服务端生成的PDF</h1><p>这是用jspdf-node生成的测试内容</p></div>'
      };
    
      try {
        const pdfBuffer = await pdf(pdfOptions);
        res.setHeader('Content-Type', 'application/pdf');
        res.setHeader('Content-Disposition', 'attachment; filename="my-pdf.pdf"');
        res.send(pdfBuffer);
      } catch (error) {
        console.error('PDF生成失败:', error);
        res.status(500).send('生成PDF出错了');
      }
    });
    
    app.listen(3000, () => console.log('服务器启动在3000端口'));
    

方案2:改用服务端原生PDF库(更推荐)

如果不想用封装包,直接用专为Node.js设计的PDF工具会更稳定,比如:

  • pdfkit:功能强大的原生Node.js PDF生成库,自定义性很高
  • html-pdf:适合把HTML页面转成PDF的场景

给你个pdfkit的简单示例:

const PDFDocument = require('pdfkit');
const express = require('express');
const app = express();

app.get('/generate-pdf', (req, res) => {
  const doc = new PDFDocument();
  
  // 设置响应头,让浏览器识别为PDF并下载
  res.setHeader('Content-Type', 'application/pdf');
  res.setHeader('Content-Disposition', 'attachment; filename="demo.pdf"');
  
  // 把PDF内容 pipe 到响应对象
  doc.pipe(res);
  
  // 添加内容
  doc.fontSize(20).text('Hello from PDFKit!', 50, 50);
  doc.fontSize(14).text('这是完全适配Node.js服务端的PDF生成工具', 50, 100);
  
  // 结束文档生成
  doc.end();
});

app.listen(3000, () => console.log('服务器运行中...'));

方案3:手动模拟浏览器环境(不推荐)

如果你非要用原生jspdf,可以用jsdom模拟出浏览器的window对象,但这种方法容易出各种奇怪的兼容问题,不推荐在生产环境用:

const { JSDOM } = require('jsdom');
const express = require('express');
const app = express();

// 模拟浏览器环境
const dom = new JSDOM('<!DOCTYPE html>');
global.window = dom.window;
global.document = dom.window.document;

// 现在可以引入原生jspdf了
const jsPDF = require('jspdf');

app.get('/test-pdf', (req, res) => {
  const doc = new jsPDF();
  doc.text('Hello World!', 10, 10);
  const pdfBuffer = doc.output('arraybuffer');
  
  res.setHeader('Content-Type', 'application/pdf');
  res.send(Buffer.from(pdfBuffer));
});

app.listen(3000);

总的来说,优先选方案1或方案2,尤其是方案2的pdfkit在服务端使用更稳定,坑更少。

内容的提问来源于stack exchange,提问作者Evans Munatsa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:36:24