使用 Node.js 在服务器上呈现 HTML

Posted

技术标签:

【中文标题】使用 Node.js 在服务器上呈现 HTML【英文标题】:HTML rendering on server with Node.js 【发布时间】:2016-04-03 10:09:13 【问题描述】:

假设我有一个网页,它只包含一个 javascript 引用。当浏览器加载页面时,它会运行 javascript,它会进行实际的渲染。 javascript 很大、很复杂,并且会进行很多XHR 调用。

现在我需要使这个页面可搜索,即在服务器上呈现页面。

我尝试在phantomJS 中加载页面,但速度很慢,有时无法完成整个页面。所以我想知道是否有替代方案。

理想情况下,我需要一个node.js 脚本来

通过 URL 加载网页 运行页面 javascript 然后 将 javascript 创建的 DOM 序列化为 html

附:我可以假设 javascript 基于 React.js

【问题讨论】:

我没有调查,只是一个想法。您可以尝试browserify 客户端javascript 并从节点内运行它并获得jsdomjquery-node-browserify (1) 的帮助吗? 【参考方案1】:

基本上你需要配置一个 node.js 服务器,对于每个请求都可以将 react 组件渲染结果作为纯字符串响应。密钥是React.renderToString。结合react-router的例子:

import express from "express";  
import React from "react";  
import Router from "react-router";  
const app = express();

// set up Jade
app.set('views', './views');  
app.set('view engine', 'jade');

import routes from "../shared/routes";

app.get('/*', function (req, res)   
  Router.run(routes, req.url, Handler => 
    let content = React.renderToString(<Handler />);
    res.render('index',  content: content );
  );
);

var server = app.listen(3000, function ()   
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);
);

React-router 有助于基于 url 加载组件,但并非绝对必要。无论如何,如果您是 React 生态系统的新手,我建议您查看 starter kit 以了解同构反应应用程序。正如您应该知道的那样,您正在尝试做的事情称为同构 Javascript。

【讨论】:

谢谢。 javascript 代码执行 XHR 调用。该套件是否支持它们? @Michael:我不知道套件的详细信息。无论如何,我认为这是两个独立的问题。一次是在服务器端呈现 JSX/HTML。另一个是你如何加载这个服务器端渲染的内容。 是的,你是对的。这是两个不同的问题。看起来我需要两个模块:XHRDOM API 作为npm 模块。【参考方案2】:

如果你要破解一些东西,为什么不这样做:

    使用轻量级节点代理模块。 将一个小的 javascript 文件注入到提供给客户端的页面中。您可以为此使用harmon (https://github.com/No9/harmon)。 在该 javascript 文件中等待页面加载完毕,然后将呈现的 HTML 发送回您的服务器。 在服务器上,检查您是否已经拥有该页面。如果您不这样做,请将其存储起来。

您可以决定何时以及如何提供“冻结”页面与动态页面。

请注意,这会使您的 React 页面静态而不是动态 - 但它们是可搜索的。也许您希望在动态呈现的类似应用程序的页面旁边有一个可搜索的存档。这将允许您执行此操作。它将渲染卸载给客户端。

可能存在登录和机密信息方面的问题,例如,如果这是一个 GMail 类型的应用程序。

但我没有在你的问题中看到任何暗示它的内容。

【讨论】:

谢谢。我当然考虑过这个解决方案 :) 这只是另一个有其自身问题的话题。【参考方案3】:

我认为 PhantomJS 和良好的缓存是迄今为止你最好的希望,除了做一个适当的服务器可渲染架构(这将是真正正确的事情)。试图在节点中模拟浏览器是愚蠢的差事。你永远不会完成它,并且会不断地发现“哎呀,我忘了另一件事了”。

许多业内同行都面临同样的问题。不要拼凑一些定制的解决方案。要么通过显式ReactDOM.renderToString() 将节点渲染设为一流并分解浏览器端代码(XHR 等),要么使用功能齐全的无头浏览器,如 PhantomJS。

【讨论】:

以上是关于使用 Node.js 在服务器上呈现 HTML的主要内容,如果未能解决你的问题,请参考以下文章

在 node.js 中使用 fabric.js 渲染和操作服务器端画布

Node.Js:资源解释为字体但使用 MIME 类型 text/html 传输

在 Node.js 中显示 Chart.js 图表

在服务器端使用 Node JS 解析 HTML [重复]

如何在运行 Node.js 的服务器上保存文件?

如何在 Node.js 服务器上部署 Vue.js 应用程序