1

这是我的问题,

  1. 我有一个前端服务器(apache 或 nginx),并且有一些配置,如 proxy_pass“iamurl/server_render/”到“backend.iamurl.com:3000/”。
  2. 我有一个在“backend.iamurl.com:3000”服务器上运行的服务器渲染 react-router 程序。(反应,反应路由器,koa2和redux)。
  3. 当我在客户端运行它时,一切都是正确的。
  4. 当我在服务器端运行它时,第一次服务器上的请求(koa2),我得到 ctx.url = / 所以路由器匹配。但是当 renderToString() 完成并且客户端收到响应时,location.path 是“/server_render”,所以 react-router 不会呈现我想要的。

我知道问题是客户端和服务器端的路径不同,但我认为这种情况(使用代理)在大公司中很常见。当浏览器收到服务器渲染响应时,如何正确运行?

我正在寻找每个人的想法。

我的路线代码(在客户端和服务器端之间共享)

    <Route path='/' component={Connector}>
        <Route component={BaseLayout}>
            <IndexRoute components={Home} onEnter={onRouteChange.bind(this, 'home')}/>
            <Route path="articleDetail/:id" components={ArticleDetail} onEnter={onRouteChange.bind(this, 'home')}/>
            <Route path="about" components={About} onEnter={onRouteChange.bind(this, 'about')}/>
            <Route path="joinUs" components={JoinUs} onEnter={onRouteChange.bind(this, 'JoinUs')}/>
        </Route>
    </Route>

这是我的服务器渲染代码

async function serverRender(ctx, next, renderProps) {
    return new Promise((resolve, reject) => {
        fetchArticlesAPI({API_URL, page: 1}, apiResult => {
            const homeReducer = {
                "home": {
                    fetched: true,
                    data: apiResult.dataList,
                    times: 1,
                    page: 1
                }
            };
            const preloadedState = {"home": homeReducer.home};
            const store = createStore(rootReducer, preloadedState);

            const html = renderToString(
                <Provider store={store}>
                    <RouterContext {...renderProps} />
                </Provider>
            );

            const finalState = store.getState();
            const finalStateToClient = JSON.stringify(finalState).replace(/</g, '\\x3c');


            const body = ctx.render('index', {
                title: "盘古首页(同构)",
                dev: argv.env === 'development',
                finalStateToClient,
                html
            });
            resolve(body);
        });
    });
}

export default async (ctx, next) => {
    const {redirectLocation, renderProps} = await _match({routes: routes, location: ctx.url});

    if (redirectLocation) {
        ctx.redirect(redirectLocation.pathname + redirectLocation.search)
    } else if (renderProps) {
        await serverRender(ctx, next, renderProps)
    } else {
        await next()
    }

}
4

0 回答 0