Node.js 生成 html

IT技术 javascript html node.js
2021-03-07 16:07:16

我创建了一个生成数据列表的 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>');

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

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

5个回答

Node.js 不在浏览器中运行,因此您将没有document可用对象。实际上,您甚至根本不会拥有 DOM 树。如果您此时有点困惑,我鼓励您在继续之前阅读更多相关信息

您可以选择几种方法来执行您想要的操作。


方法 1:直接通过 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

编辑:您也可以使用小型HTTP 服务器为它们提供服务。)


方法 2:仅生成文件

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

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


方法三:直接将文件转储到 stdout

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

var html = buildHtml();

console.log(html);

注:buildHtml功能是完全相同的相同方法1(再次)

如果您的脚本被调用html-generator.js(例如),在基于 Linux/Unix 的系统中,只需执行

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

结论

因为 Node 是一个module化系统,你甚至可以把buildHtml函数放在它自己的module中,然后简单地编写适配器来处理你喜欢的 HTML。就像是

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

var html = htmlBuilder(options);
...

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

额外阅读,了解npm希望这可以帮助。

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

尽管@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 不会自动执行此操作。
2021-04-29 16:07:16
@OneHoopyFrood 您缺少哪些必需的标头?内容长度?对于动态生成的内容来说,这是一个艰难的要求。内容类型默认为 text/html,编码默认为 latin1,所以这一切都很好。这对于快速和肮脏的脚本是有效的和伟大的。
2021-04-30 16:07:16

如果你想创建静态文件,你可以使用Node.js 文件系统库来做到这一点。但是,如果您正在寻找一种根据数据库或类似查询创建动态文件的方法,那么您将需要一个像SWIG这样的模板引擎除了这些选项之外,您始终可以像往常一样创建 HTML 文件,并通过 Node.js 提供它们。为此,您可以使用Node.js 文件系统从 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
2021-04-22 16:07:16
你是对的亚尼克。我只是保持代码简单以使其更易于理解:)。在生产服务器上,我无论如何都会使用 ExpressJS 的静态文件服务功能。
2021-05-14 16:07:16

你可以使用jsdom

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

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

您可以使用翡翠+快递:

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

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