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

IT技术 javascript html node.js reactjs phantomjs
2021-05-16 08:39:15

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

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

我试图加载页面,phantomJS但它很慢,有时没有完成整个页面。所以我想知道是否有替代方案。

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

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

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

3个回答

本质上,您需要配置一个 node.js 服务器,它可以为每个请求响应 React 组件渲染结果作为纯字符串。关键是React.renderToStringreact-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 生态系统的新手,我建议您查看这个用于同构 React 应用程序的入门套件正如您应该知道的那样,您尝试做的是同构 Javascript。

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

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

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

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

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

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

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

您在行业中的许多同行都面临着同样的问题。不要拼凑一些定制的解决方案。要么通过显式ReactDOM.renderToString()并分解出浏览器端代码(XHR 等)来使节点呈现一流,要么使用像 PhantomJS 这样功能齐全的无头浏览器。