Express.js服务器端渲染 – 请求'/ json / version /

我有一个快速服务器运行,以预渲染我的反应的应用程序。 我有一个路线文件,匹配的HomeContainer基地的路线/和所有其他路线匹配找不到页面。

 import HomeContainer from 'containers/home-container/home-container'; import PageNotFound from 'components/page-not-found/page-not-found'; const routes = [ { path: '/', exact: true, component: HomeContainer }, { path: '*', component: PageNotFound } ]; export default routes; 

我遇到的问题是,当我在服务器上运行应用程序时,页面未find路由获取呈现之前,快速更改为HomeContainer路线。

我已经发现,这是因为我的快递服务器向/json/version发出请求,然后向/发送请求,此路由与我的路由文件中的路由不匹配,因此未find页面组件。

现在我没有得到的是为什么它正在提出这个请求,以及如何停止在home容器之前page not found组件。 我试过debugging节点服务器和最早的地方,我可以find这个path被引用是在一个名为_http_server.js

以下是debugging器的屏幕截图,以及我在哪里find正在引用的URL。

调试器截图

另外作为参考,我已经包括我的快递服务器下面。

 import express from 'express'; import React from 'react'; import { renderToString } from 'react-dom/server'; import { Provider } from 'react-redux'; import { StaticRouter, matchPath } from 'react-router-dom'; import serialize from 'serialize-javascript'; import expressStaticGzip from 'express-static-gzip'; import sourceMapSupport from 'source-map-support'; import routes from 'routes'; import configureStore from 'store'; import AppContainer from 'containers/app-container/app-container'; if (process.env.NODE_ENV === 'development') { sourceMapSupport.install(); } const app = express(); app.use(expressStaticGzip('./static/assets')); app.get('*', (req, res, next) => { const store = configureStore(); /** * Load initial data into state * match requested URL path to the component in routes * check for 'fireInitialActions' method (found in the container components) * and dispatch if it exists */ const routeComponentPromises = routes.reduce((accumulator, route) => { if (matchPath(req.url, route) && route.component && route.component.fireInitialActions) { accumulator.push(Promise.resolve(store.dispatch(route.component.fireInitialActions()))); } return accumulator; }, []); Promise.all(routeComponentPromises) .then(() => { const context = {}; const markup = renderToString( <Provider store={store}> <StaticRouter location={req.url} context={context}> <AppContainer /> </StaticRouter> </Provider> ); const initialData = store.getState(); res.send(` <!DOCTYPE html> <html> <head> <title>Test</title> <script src='vendor.js' defer></script> <script src='app.js' defer></script> <script>window.__initialData__ = ${serialize(initialData)}</script> </head> <body> <div id="root">${markup}</div> </body> </html> `); }) .catch(next); }); app.listen(process.env.PORT || 3000, () => { console.log('Server is listening'); }); 

有谁知道为什么会发生这种情况,我怎么能解决我的问题?

编辑:这是一个video显示的问题 – https://d26dzxoao6i3hh.cloudfront.net/items/2z3y3f1x3N1D2e422W42/Screen%20Recording%202017-10-23%20at%2012.24%20pm.mov

不是100%确定是什么原因造成的问题,但我现在已经修复了。

我做的两个主要的改变是

  1. 使用EJS作为模板引擎
  2. 在gzip插件中将indexFromEmptyFile设置为false

2号似乎是非常重要的,没有它表示试图服务index.html而不是index.ejs ,这导致了同样的问题,因为index.html与我的路线文件中的路线不匹配。

以下是更新的代码

 import express from 'express'; import React from 'react'; import { renderToString } from 'react-dom/server'; import { Provider } from 'react-redux'; import { StaticRouter, matchPath } from 'react-router-dom'; import serialize from 'serialize-javascript'; import sourceMapSupport from 'source-map-support'; import expressStaticGzip from 'express-static-gzip'; import routes from 'routes'; import configureStore from 'store'; import AppContainer from 'containers/app-container/app-container'; if (process.env.NODE_ENV === 'development') { sourceMapSupport.install(); } const app = express(); app.set('views', './static/'); app.set('view engine', 'ejs'); app.use(expressStaticGzip('static/assets', { indexFromEmptyFile: false })); app.get('*', (req, res, next) => { const store = configureStore(); /** * Load initial data into state * match requested URL path to the component in routes * check for 'fireInitialActions' method (found in the container components) * and dispatch if it exists * return as promises so we can chain */ const routeComponentPromises = routes.reduce((accumulator, route) => { if (matchPath(req.url, route) && route.component && route.component.fireInitialActions) { accumulator.push(Promise.resolve(store.dispatch(route.component.fireInitialActions()))); } return accumulator; }, []); Promise.all(routeComponentPromises) .then(() => { const context = {}; const markup = renderToString( <Provider store={store}> <StaticRouter location={req.url} context={context}> <AppContainer /> </StaticRouter> </Provider> ); const initialData = serialize(store.getState()); res.render('index.ejs', {initialData, markup}); }) .catch(next); }); app.listen(process.env.PORT || 3000, () => { console.log('Server is listening'); });`