使用客户端路由

时间:2015-06-21 08:29:41

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

我的主页路由(/)的初始服务器呈现正常。

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

2 个答案:

答案 0 :(得分:4)

停止使用哈希驱动的导航。在#之后出现的所有内容都只是客户端而对此类事情无用。因此/#/page2需要成为/page2

我不确定是否有反应,但其他路由系统存在同样的问题,并且很容易关闭网址中的#

在angular的ui-router中就像这样$locationProvider.html5Mode(true);

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

答案 1 :(得分: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);
});

第二:确保您的节点页面路由全部返回相同的&#34; index.ejs&#34;。否则,您的路线(例如 / 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});
  });
});

此外:如果您正在提供&#34; public&#34;静态资产,在您的路由之前声明,并删除任何 public / index.html ,以便您的节点路由器处理 / 请求并提供服务器内容。