使用react-router的服务器端呈现无效

时间:2016-01-31 23:33:04

标签: react-router

我使用快递,我想做一些基本的路由服务器端。目前我只想设置路由器来执行任何。现在它总是返回404。

我相信我已按照https://github.com/rackt/react-router/blob/master/docs/guides/advanced/ServerRendering.md上列出的说明进行操作。

它基本上是你能得到的:一个快速服务器,用于路由上面列出的链接代码处理的每个请求,以及一个将所有内容路由到AppTemplate组件的ReactRouter。

它肯定会在routes.js中进行回调,因为它会返回' Not found'对于每个请求。

我怀疑这很重要,但我通过iisnode在IIS中运行它。我一直在调试问题,这是我通过<Router>从快速反应视图切换到路由的原因之一。

让我知道我可以获得的其他信息。

文件结构:

server/
-- server.js // just calls babel-register and express-app.js
-- express-app.js
-- router.js

server/views/
-- app-template.js
-- routes.js

服务器/表达-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');

服务器/ 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');
        }
    });
});

服务器/视图/ 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>
);

服务器/视图/ 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>
        );
    }
};

1 个答案:

答案 0 :(得分:2)

几个星期前我遇到了麻烦,但不知何故让它发挥作用,这里有一些我做了不同的事情,可能会或可能不会影响你的实施:

  1. 而不是使用express.get,我使用了没有路径规范的express.use,这意味着react-router更像中间件而不是请求处理程序。

  2. 在匹配的第一个参数中,我的对象键是&#34; routes&#34;而不是&#34;路线&#34;

  3. 我正在使用&#39;历史记录&#39;模块也是如此,所以我的位置是使用createLocation(req.originalUrl)创建的 - createLocation来自&#39; history&#39;。

  4. 尝试给这些东西一个镜头,否则我也可以发布我的代码的改编版本。

    OP注意:

    是#2。 babel语法Routes将对象扩展为具有match()的密钥,routes期望密钥为import routes from './views/routes'; ... { routes, location: req.url } 。这可以通过制作

    来解决
    import Routes from './views/routes';
    ...
    { routes: Routes, location: req.url }
    
    建议

    ,或

    // src/AppBundle/Controller/SecurityController.php
    
    // ...
    use Symfony\Component\HttpFoundation\Request;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
    
    class SecurityController extends Controller
    {
        /**
         * @Route("/login", name="login_route")
         */
        public function loginAction(Request $request)
        {
        }
    
        /**
         * @Route("/login_check", name="login_check")
         */
        public function loginCheckAction()
        {
            // this controller will not be executed,
            // as the route is handled by the Security system
        }
    }