使用Node.js在服务器上进行HTML渲染

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

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

我试图加载页面phantomJS但它是缓慢的,有时并没有完成整个页面。 所以我想知道是否有其他select。

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

  • 通过URL加载网页
  • 运行的JavaScript页面,然后
  • 将由javascript创build的DOM序列化为HTML。

PS我可以假设JavaScript是基于React.js

本质上,您需要configuration一个node.js服务器,以便每个请求都可以将反应组件渲染结果作为纯string进行响应。 关键是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加载组件,但并不是绝对必要的。 无论如何,如果你是新的反应生态系统,我build议你看看这个入门套件的同构反应应用程序。 正如你应该知道你正在尝试做什么叫做同构的Javascript。

我认为PhantomJS和良好的caching是你迄今为止最好的希望,除了做一个合适的服务器可渲染的体系结构(这将是实际的正确的事情)。 试图模拟节点中的浏览器是一个傻瓜的差事。 你将永远不会完成它,并不断地发现“哎呀,我忘了那另一件事”不rest。

业内许多同行都面临同样的问题。 不要凑齐一些定制的解决scheme。 可以通过显式的ReactDOM.renderToString()使节点渲染成为第一类,并分解浏览器端代码(XHR等),或者使用像PhantomJS这样的function齐全的无头浏览器。

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

  1. 使用轻量级节点代理模块。
  2. 注入一个小的JavaScript文件到提供给客户端的页面。 你可以使用和声( https://github.com/No9/harmon )。
  3. 在该JavaScript文件等待,直到加载页面,然后将呈现的HTML发回到您的服务器。
  4. 在服务器上,检查您是否已经有该页面。 如果你不这样做,那么存储它。

您可以决定何时以及如何为页面的“冻结”版本与dynamic版本提供服务。

请注意,这使得您的React页面是静态的而不是dynamic的 – 但是它们是可search的。 也许你想要一个可search的存档与dynamic呈现的类似应用程序的页面一起。 这可以让你做到这一点。 它将渲染卸载到客户端。

例如,如果这是一个GMailtypes的应用程序,可能会有login和机密信息的问题。

但是我没有看到你的问题中有任何暗示。