【问题标题】:Node.js Generate htmlNode.js 生成 html
【发布时间】:2014-03-04 06:11:35
【问题描述】:

我创建了一个生成数据列表的 JavaScript 程序。下面的示例输出:

output one 
output two 
output three 
...

我希望能够生成一个可以保存到磁盘并使用浏览器打开的 HTML 文件。下面是我要生成的 HTML 示例。

<html>
    <head>
    </head>
    <body>
        <table id="history_table">
            <tr>
                <td>header 1</td>
                <td>header 2</td>
                <td>header 3</td>
            </tr>
            <tr>
               <td>output one</td>
            </tr>
            ...
        </table>
    </body>
</html>

我试过这样做:

var htmlDoc = document.createElement("HMTL");
htmlDoc.innerhtml('<head></head><body>...</body>');

但这显然是错误的,因为文档对象不存在。

我认为这个问题是有道理的,尤其是从它收到的赞成票数量来看。可以重新打开吗?

【问题讨论】:

  • 有很多关于如何提供页面模板的节点示例。特别是如果您查看 ExpressJS。尽管您的代码中没有一部分显示与 NodeJS 有任何关系...我想知道您是否对 NodeJS 是什么感到困惑...
  • Nodejs 没有开箱即用的 DOM 操作。您必须安装相关库才能执行此类操作。我即将尝试node-dom,但你可以自己研究一下这个方向
  • 我不知道为什么这个问题最初被关闭。有很多点赞和 4 星,以及详细的答案(无耻的插头),海报的意图非常明确。我的两分钱。
  • 我不确定是否有人可以改变这一点,但我同意,答案帮助我分配和其他一些人

标签: javascript html node.js


【解决方案1】:

Node.js 不在浏览器中运行,因此您将没有可用的document 对象。实际上,您甚至根本没有 DOM 树。如果你在这一点上有点困惑,我鼓励你在继续之前read more about it

您可以选择几种方法来做您想做的事。


方法一:直接通过HTTP服务文件

因为您写的是在浏览器中打开文件,为什么不使用将文件直接作为 HTTP 服务提供服务的框架,而不是使用两步过程?这样,您的代码将更加动态且易于维护(更不用说您的 HTML 始终是最新的)。

有很多框架可以做到这一点:

你可以做你想做的最基本的方法是:

var http = require('http');

http.createServer(function (req, res) {
  var html = buildHtml(req);

  res.writeHead(200, {
    'Content-Type': 'text/html',
    'Content-Length': html.length,
    'Expires': new Date().toUTCString()
  });
  res.end(html);
}).listen(8080);

function buildHtml(req) {
  var header = '';
  var body = '';

  // concatenate header string
  // concatenate body string

  return '<!DOCTYPE html>'
       + '<html><head>' + header + '</head><body>' + body + '</body></html>';
};

然后在您的浏览器中使用 http://localhost:8080 访问此 HTML。

编辑:你也可以用一个小的HTTPserver为他们服务。)


方法二:只生成文件

如果您想要做的只是生成一些 HTML 文件,那就简单点。为了在文件系统上执行 IO 访问,Node 有一个 API,记录在 here

var fs = require('fs');

var fileName = 'path/to/file';
var stream = fs.createWriteStream(fileName);

stream.once('open', function(fd) {
  var html = buildHtml();

  stream.end(html);
});

注意:buildHtml 函数与方法1中的完全相同


方法三:直接将文件dump到stdout

这是最基本的 Node.js 实现,需要调用应用程序自己处理输出。要在 Node 中输出一些东西(即到 stdout),最好的方法是使用 console.log(message) 其中message 是任何字符串或对象等。

var html = buildHtml();

console.log(html);

注意:buildHtml 函数完全方法 1(再次)中的相同

如果您的脚本名为html-generator.js(例如),在基于 Linux/Unix 的系统中,只需这样做

$ node html-generator.js > path/to/file

结论

因为 Node 是一个模块化系统,你甚至可以将 buildHtml 函数放在它自己的模块中,然后简单地编写适配器来处理你喜欢的 HTML。类似的东西

var htmlBuilder = require('path/to/html-builder-module');

var html = htmlBuilder(options);
...

在为 Node.js 编写 JavaScript 时,您必须考虑“服务器端”而不是“客户端”;您不在浏览器中和/或仅限于 V8 引擎以外的沙箱。

额外阅读,了解npm。希望这会有所帮助。

【讨论】:

  • 我没有发现服务器上不存在 Document 对象的原因。我们不要忘记客户端上的 window.document 是什么:一个 XML 文档实例,其方法允许您进行 DOM 操作。我们应该(并且可以)使用任何语言在服务器上进行 DOM 操作
  • @Loupax,这里的问题不是您是否可以,而是默认情况下是否有一个。服务器端 JavaScript 没有全局 window 对象。它也没有文档。它可以有,但不需要。因此,除非您创建或添加其中任何一个的实现,否则它们将不存在。尽量不要将新手程序员与 Node.js 混淆。服务器端编程和客户端编程必须有区别;两者都使用相同的语言和语法,但不共享相同的权限和容器。
  • 也许吧,但当问题是关于“我如何在服务器上进行 DOM 操作”并且所有答案都是“你不能”时,我发现它有点不对劲。您可能需要安装一个库,但您可以。这至少值得一提 IMO
  • @Loupax 我相信您误读了这个问题。它不是关于 DOM 操作,而是关于生成 HTML。唯一提到 Document 对象是 OP 试图做的,这就是为什么我说“你不能那样做”,我对此 100% 正确;他混淆了浏览器的 JavaScript 和 Node.js 应用程序中的 JavaScript。我再说一遍,这与您是否可以进行 DOM 操作无关。现在,请重新阅读问题和我的回答,不要再争论了。
【解决方案2】:

您可以使用jsdom

const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const { document } = (new JSDOM(`...`)).window;

或者,看看cheerio,它可能更适合你的情况。

【讨论】:

    【解决方案3】:

    可以用jade+快递:

    app.get('/', function (req, res) { res.render('index', { title : 'Home' } ) });
    

    在你上面看到'index'和一个对象 {title : 'Home'},'index' 是你的 html 并且对象是将在您的 html 中呈现的数据。

    【讨论】:

      【解决方案4】:

      如果你想创建静态文件,你可以使用Node.js File System Library 来做到这一点。但是,如果您正在寻找一种通过数据库或类似查询来创建动态文件的方法,那么您将需要像 SWIG 这样的模板引擎。除了这些选项之外,您还可以像往常一样创建 HTML 文件并通过 Node.js 提供它们。为此,您可以使用 Node.js File System 从 HTML 文件中读取数据并将其写入响应。一个简单的例子是:

      var http = require('http');
      var fs   = require('fs');
      
      http.createServer(function (req, res) {
        fs.readFile(req.params.filepath, function (err, content) {
          if(!err) {
            res.end(content);
          } else {
            res.end('404');
          }
        }
      }).listen(3000);
      

      但我建议您研究一些框架,例如 Express,以获得更有用的解决方案。

      【讨论】:

      • 只是关于这个答案的注释;不要在生产中使用这样的代码:) 因为req.params.filepath 很可能是一个值,例如/etc/passwd 或类似的东西。
      • 你是对的 Yanick。我只是保持代码简单以使其更易于理解:)。在生产服务器上,无论如何我都会使用 ExpressJS 的静态文件服务功能。
      【解决方案5】:

      虽然@yanick-rochon 的回答是正确的,但实现目标的最简单方法(如果是提供动态生成的 html)是:

      var http = require('http');
      http.createServer(function (req, res) {
        res.write('<html><head></head><body>');
        res.write('<p>Write your HTML content here</p>');
        res.end('</body></html>');
      }).listen(1337);
      

      这样,当您浏览 http://localhost:1337 时,您将获得您的 html 页面。

      【讨论】:

      • -1 这不提供 HTTP 标准所需的任何标头信息。 Node 不会自动执行此操作。
      • @OneHoopyFrood 您缺少哪些必需的标头?内容长度?对于动态生成的内容,这是一个很难的要求。内容类型默认为 text/html,编码默认为 latin1,所以这应该都很好。这对于快速和肮脏的脚本是有效的并且非常有用。
      猜你喜欢
      • 2016-11-14
      • 2015-12-16
      • 2015-03-17
      • 1970-01-01
      • 2011-09-25
      • 2018-07-19
      • 1970-01-01
      • 2019-09-14
      • 2013-11-04
      相关资源
      最近更新 更多