【问题标题】:NodeJs says "ReferenceError: window is not defined" with jsPDFNodeJs 用 jsPDF 说“ReferenceError: window is not defined”
【发布时间】:2018-11-09 14:32:18
【问题描述】:

我正在使用 NodeJs 和 jsPDF 创建一个示例项目。当我运行时,它会回显ReferenceError: window is not defined。我也使用了来自hereJohn Gordon 答案,但同样的问题。

我试过了

var express = require('express');
var jsPDF = require('jspdf');
var app = express();

app.get('/', function(req, res)
{
    global.window = {document: {createElementNS: () => {return {}} }};
    global.navigator = {};
    global.btoa = () => {};

    var fs = require('fs');
    var jsPDF = require('jspdf');
    var jsPDFTable = require('jspdf-autotable');

    var doc = new jsPDF();
    doc.text("Hello", 10, 10);
    var data = doc.output();

    fs.writeFileSync('./tmp/storage/pdf/document.pdf', data);

    delete global.window;
    delete global.navigator;
    delete global.btoa;
});

var port = process.env.PORT || 8080;
app.listen(port);
console.log('Server started');

module.exports = app;

【问题讨论】:

  • jsPDF 看起来像是一个浏览器模块,而不是一个 Node 模块。
  • 尝试使用脚本标签来包含在浏览器中:<script src="https://unpkg.com/jspdf@latest/dist/jspdf.min.js"></script>
  • @FaizuddinMohammed,我应该在哪里使用这个脚本?
  • 当然是在您的浏览器中。
  • 在浏览器中,我用http://localhost:8080/ 观看。那怎么办?

标签: node.js jspdf


【解决方案1】:

您需要做的就是删除顶部的var jsPDF = require('jspdf');,并在您的app.get..(您已经拥有)函数中添加类似的声明,

var express = require('express');
var app = express();

app.get('/', function(req, res)
{
    global.window = {document: {createElementNS: () => {return {}} }};
    global.navigator = {};
    global.btoa = () => {};

    var fs = require('fs');
    var jsPDF = require('jspdf');
    var jsPDFTable = require('jspdf-autotable');

    var doc = new jsPDF();
    doc.text("Hello", 10, 10);
    var data = doc.output();

    fs.writeFileSync('./document.pdf', data);

    delete global.window;
    delete global.navigator;
    delete global.btoa;
});

var port = process.env.PORT || 8080;
app.listen(port);
console.log('Server started');

module.exports = app;

希望这会有所帮助!

【讨论】:

  • 感谢您的代码。它工作正常,没有我之前提到的错误。
【解决方案2】:

指定的包jspdf是客户端专用库,需要在浏览器环境中使用才能正常工作。

包首页描述清楚:

在客户端 JavaScript 中生成 PDF 的库。

现在,npm 包可用的原因是因为像 Webpack 和 Browserify 这样的打包工具可以加载 npm 包并将它们转换为适当的浏览器兼容脚本。 require() 未在浏览器环境中定义,没有这些捆绑器将无法工作。

所以,要么选择一个支持 NodeJS 的库,比如 https://www.npmjs.com/package/pdfkit 或将您的 PDF 相关代码转移到浏览器并使用它。

编辑: https://github.com/MrRio/jsPDF/issues/566#issuecomment-382039316

表明您可以通过进行以下更改在 NodeJS env 中使用该库。

在这种情况下,您需要在require模块之前定义全局变量。

global.window = {document: {createElementNS: () => {return {}} }};
global.navigator = {};
global.btoa = () => {};

var fs = require('fs');
var jsPDF = require('jspdf');
var jsPDFTable = require('jspdf-autotable'); 
var app = require('express')();



app.get('/', function(req, res)
{
   var doc = new jsPDF();
   // ...
}

【讨论】:

  • @Faizuddin Mohammed,感谢您的努力和精彩的解释
【解决方案3】:

您可以将脚本标签放在html页面的head标签或body标签中,任何一个都可以。要决定放置位置,this answer 可能会有所帮助

【讨论】:

  • 为什么会这样?你能给我做个例子吗?
  • 实际上我意识到你在服务器端这样做,所以我同意@Faizuddin Mohammed。如果要在服务器端生成 pdf,在这种情况下是节点应用程序,则需要使用 node-jspdf 而不仅仅是 jspdf。以node-jspdf 为例。
  • var doc = jsPDF(); doc.text(20, 20, 'Hello, world.'); doc.save('Test.pdf', function(err){console.log('saved!');});
猜你喜欢
  • 1970-01-01
  • 2019-02-08
  • 2018-10-28
  • 2018-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多