Javascript 使用客户端路由进行服务器端渲染

Javascript 使用客户端路由进行服务器端渲染,javascript,reactjs,single-page-application,isomorphic-javascript,Javascript,Reactjs,Single Page Application,Isomorphic Javascript,我的主页路径(/)的初始服务器呈现工作正常 此外,后续客户端导航到(/#/page2)也可以正常工作 但是,如果我直接从地址栏加载/#/page2,服务器呈现的主页将首先在浏览器中加载,然后明显地过渡到/#/page2,这不是我想要的。我只想显示/#/page2,而不首先刷新主页 发生的情况是,节点正在为请求/提供主页,然后当响应到达客户端时,客户端正在运行/#/page2的路由处理程序。两人的行为都是正确的。但这不是我想要的 我如何避免这种行为 我想我需要的是一种方法,让服务器和客户端都知道不

我的主页路径(/)的初始服务器呈现工作正常

此外,后续客户端导航到(/#/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});
  })
});
router.get('/',函数(req,res){
var React=要求('React');
var-Router=require('react-Router');
var Routes=require(“../app/clapi Routes.jsx”);
var router=router.create({location:req.url,routes:routes});
run(函数(处理程序,状态){
var html=React.renderToString();
返回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>

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

我不确定react是否正确,但其他路由系统也存在同样的问题,因此很容易关闭URL中的

在angular的ui中,路由器是这样做的
$locationProvider.html5Mode(true)


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

我发现有两个步骤:

首先:将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);
});
//在app.jsx(客户端路由)中
Router.run(批准、Router.HistoryLocation、函数(处理程序){
React.render(,document.body);
});
Second:确保节点页面路由都返回相同的“index.ejs”。否则,您的路由(如/page2将在整页刷新(或deeplink)时显示404

//在server.js(服务器端路由)中
router.get('*',函数(req,res){
Router.run(路由、请求路径、函数(处理程序){
var html=React.renderToString();
返回res.render('index.ejs',{html:html});
});
});

此外:如果您正在为“公共”静态资产提供服务,请在您的路线之前声明:,并删除您可能拥有的任何public/index.html,以便您的节点路由器使用服务器呈现的内容处理/请求。

您是否能够编写一个小的JSFIDLE/plnkr来说明您的问题?@harshtuna如何处理节点服务器代码?@joehanik@joehanik忽略了SSR的要点。也许用这个做演示?@jantimon,太酷了。如果需要,我可以复制我的项目。现在,这里有一个屏幕记录的行为:你是正确的。我在下面贴了一个对我有用的完整答案。
// 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});
  });
});