使用 react-router 的服务器端渲染不起作用
Server-side rendering with react-router is not working
我正在使用 express,我想在服务器端做一些基本的路由。目前我只是想设置路由器来做任何事情。现在它总是 returns 一个 404.
我相信我已经按照 https://github.com/rackt/react-router/blob/master/docs/guides/advanced/ServerRendering.md 上列出的说明进行操作。
它是您所能得到的最基本的:一个快速服务器,用于路由每个请求以由上面列出的 link 中的代码处理,以及一个将所有内容路由到 AppTemplate 组件的 ReactRouter。
它肯定会到达 routes.js 中的回调,因为它 returns 'Not found' 每个请求。
我怀疑它是否重要,但我通过 iisnode 在 IIS 中 运行 它。我在调试时遇到了麻烦,这是我从 express-react-views 切换到通过 <Router>
.
路由的原因之一
让我知道我还能为您提供哪些其他信息。
文件结构:
server/
-- server.js // just calls babel-register and express-app.js
-- express-app.js
-- router.js
server/views/
-- app-template.js
-- routes.js
server/express-app.js
import Express from 'express';
import BodyParser from 'body-parser';
import CookieParser from 'cookie-parser';
let app = new Express();
export default app;
app.enable('trust proxy');
app.use('/public', Express.static('../dist'));
app.use(BodyParser.urlencoded({ extended: true }));
app.use(BodyParser.json());
app.use(CookieParser());
// some rest API code here, currently commented out
app.set('tokenSecret', process.env.tokenSecret);
require('./router');
server/router.js
// copied right from https://github.com/rackt/react-router/blob/master/docs/guides/advanced/ServerRendering.md.
import { renderToString } from 'react-dom/server';
import { match, RouterContext} from 'react-router';
import app from './express-app';
import Routes from './views/routes';
app.get('/*', (req, res) => {
match({ Routes, location: req.originalUrl }, (error, redirectLocation, renderProps) => {
if (error) {
res.status(500).send(error.message);
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search);
} else if (renderProps) {
res.status(200).send(renderToString(<RouterContext {...renderProps} />));
} else {
res.status(404).send('Not found');
}
});
});
server/views/routes.js
import React from 'react';
import {Router, Route, IndexRoute} from 'react-router';
import AppTemplate from './app-template';
export default (
<Router>
<Route path='/' component={AppTemplate}>
</Route>
</Router>
);
server/views/app-template.js
import React from 'react';
export default class AppTemplate extends React.Component {
constructor() {
super();
}
render() {
return (
<html>
<head>
</head>
<body>
<div id='app' />
</body>
</html>
);
}
};
几周前我遇到了这个问题,但不知何故让它工作了,这里有一些我做的不同的事情可能会或可能不会影响你的实施:
我没有使用 express.get,而是使用了没有指定路径的 express.use,这意味着 react-router 更像是中间件而不是请求处理程序。
在要匹配的第一个参数中,我的对象键是 "routes" 而不是 "Routes"
我也在使用 'history' 模块,所以我的位置是使用 createLocation(req.originalUrl) 创建的 - createLocation 来自 'history'.
试试这个东西,否则我也可以 post 我的代码的改编版本。
OP 备注:
这是#2。 babel 语法 { Routes, location: req.url }
将对象扩展为具有 Routes
的键,而 match()
期望键为 routes
。这可以通过
来解决
import routes from './views/routes';
...
{ routes, location: req.url }
按照建议,或
import Routes from './views/routes';
...
{ routes: Routes, location: req.url }
我正在使用 express,我想在服务器端做一些基本的路由。目前我只是想设置路由器来做任何事情。现在它总是 returns 一个 404.
我相信我已经按照 https://github.com/rackt/react-router/blob/master/docs/guides/advanced/ServerRendering.md 上列出的说明进行操作。
它是您所能得到的最基本的:一个快速服务器,用于路由每个请求以由上面列出的 link 中的代码处理,以及一个将所有内容路由到 AppTemplate 组件的 ReactRouter。
它肯定会到达 routes.js 中的回调,因为它 returns 'Not found' 每个请求。
我怀疑它是否重要,但我通过 iisnode 在 IIS 中 运行 它。我在调试时遇到了麻烦,这是我从 express-react-views 切换到通过 <Router>
.
让我知道我还能为您提供哪些其他信息。
文件结构:
server/
-- server.js // just calls babel-register and express-app.js
-- express-app.js
-- router.js
server/views/
-- app-template.js
-- routes.js
server/express-app.js
import Express from 'express';
import BodyParser from 'body-parser';
import CookieParser from 'cookie-parser';
let app = new Express();
export default app;
app.enable('trust proxy');
app.use('/public', Express.static('../dist'));
app.use(BodyParser.urlencoded({ extended: true }));
app.use(BodyParser.json());
app.use(CookieParser());
// some rest API code here, currently commented out
app.set('tokenSecret', process.env.tokenSecret);
require('./router');
server/router.js
// copied right from https://github.com/rackt/react-router/blob/master/docs/guides/advanced/ServerRendering.md.
import { renderToString } from 'react-dom/server';
import { match, RouterContext} from 'react-router';
import app from './express-app';
import Routes from './views/routes';
app.get('/*', (req, res) => {
match({ Routes, location: req.originalUrl }, (error, redirectLocation, renderProps) => {
if (error) {
res.status(500).send(error.message);
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search);
} else if (renderProps) {
res.status(200).send(renderToString(<RouterContext {...renderProps} />));
} else {
res.status(404).send('Not found');
}
});
});
server/views/routes.js
import React from 'react';
import {Router, Route, IndexRoute} from 'react-router';
import AppTemplate from './app-template';
export default (
<Router>
<Route path='/' component={AppTemplate}>
</Route>
</Router>
);
server/views/app-template.js
import React from 'react';
export default class AppTemplate extends React.Component {
constructor() {
super();
}
render() {
return (
<html>
<head>
</head>
<body>
<div id='app' />
</body>
</html>
);
}
};
几周前我遇到了这个问题,但不知何故让它工作了,这里有一些我做的不同的事情可能会或可能不会影响你的实施:
我没有使用 express.get,而是使用了没有指定路径的 express.use,这意味着 react-router 更像是中间件而不是请求处理程序。
在要匹配的第一个参数中,我的对象键是 "routes" 而不是 "Routes"
我也在使用 'history' 模块,所以我的位置是使用 createLocation(req.originalUrl) 创建的 - createLocation 来自 'history'.
试试这个东西,否则我也可以 post 我的代码的改编版本。
OP 备注:
这是#2。 babel 语法 { Routes, location: req.url }
将对象扩展为具有 Routes
的键,而 match()
期望键为 routes
。这可以通过
import routes from './views/routes';
...
{ routes, location: req.url }
按照建议,或
import Routes from './views/routes';
...
{ routes: Routes, location: req.url }