2

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

此外,随后的客户端导航到 ( /#/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>
4

2 回答 2

4

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

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

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

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

于 2015-06-21T10:07:48.963 回答
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,以便您的节点路由器处理/请求与服务器呈现的内容。

于 2015-06-22T02:12:32.150 回答