【问题标题】:react server side rendering with client side routing用客户端路由反应服务器端渲染
【发布时间】:2015-09-06 21:10:57
【问题描述】:

我的主页路由 ( / ) 的初始服务器渲染工作正常。

此外,随后的客户端导航到 ( /#/page2 ) 工作正常。

但是,如果我直接从地址栏加载 /#/page2,服务器渲染的主页首先会加载到浏览器中,然后明显地转换到 /#/page2,这不是我想要的。我只想显示 /#/page2 而无需先刷新主页。

发生的事情是节点正在为 / 的请求提供主页,然后当响应到达客户端时,客户端正在运行 /#/page2 的路由处理程序。两者的行为都正确。但这不是我想要的。

如何避免这种行为?

我认为我需要一种让服务器和客户端都知道不同路由并且都能够处理它们(同构)的方法,但是,服务器不知道 url 的片段部分.

其他人有这个问题吗?

这个问题不是特定的反应。它是特定于 SSR 的深层链接。

我的节点路由器处理“/”如下

router.get('/', function(req, res) {
  var React = require('react');
  var Router = require('react-router');
  var Routes = require("../app/clapi-routes.jsx");

  var router = Router.create({location: req.url, routes: Routes});
  router.run(function(Handler, state) {
    var html = React.renderToString(<Handler/>);
    return res.render('index.ejs', {html:html});
  })
});

index.ejs 只是:

<html lang="en">
  <head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="/css/json-inspector.css"/>
  </head>
<body style="margin:0">
  <%- html %>
  <script src="/build/bundle.js"></script>
</body>
</html>

【问题讨论】:

标签: javascript reactjs single-page-application isomorphic-javascript


【解决方案1】:

我发现有两个步骤:

首先: 将 react 路由器更改为使用 Router.HistoryLocation 而不是默认的 (HashLocation)。这使您的路由使用 html5 推送状态并将您的路由路径从 /#/page2 更改为 /page2

// in app.jsx (client side routing)

Router.run(AppRoutes, Router.HistoryLocation, function(Handler) {
  React.render(<Handler/>, document.body);
});

第二:确保您的节点页面路由都返回相同的“index.ejs”。否则,您的路线,如 /page2 将在整页刷新(或深层链接)时出现 404

// in server.js (server side routing)

router.get('*', function(req, res) {
  Router.run(Routes, req.path, function(Handler) {
    var html = React.renderToString(<Handler/>);
    return res.render('index.ejs', {html: html});
  });
});

另外:如果您提供“公共”静态资产,请在您的路由之前声明,并删除所有 public/index.html您可能需要让您的节点路由器处理带有服务器呈现内容的 / 请求。

【讨论】:

    【解决方案2】:

    停止使用哈希驱动的导航。 # 之后的所有内容都只是客户端,对于这样的事情毫无用处。所以/#/page2需要变成/page2

    我不确定是否会做出反应,但其他路由系统也存在同样的问题,并且在 url 中关闭 # 真的很容易。

    在 Angular 的 ui-router 中是这样完成的 $locationProvider.html5Mode(true);

    您的服务器端需要知道才能对您的客户端知道的所有 URL 做出反应,但这就是实现稳健性的方式 - 无论导航如何发生(客户端事件或链接点击),客户端和服务器都可以端到端地处理场景。

    【讨论】:

    • 你是对的。我在下面发布了一个对我有用的完整答案。
    猜你喜欢
    • 2015-05-09
    • 2017-12-29
    • 2021-07-31
    • 2016-05-26
    • 2018-02-05
    • 2016-02-05
    • 2021-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多