ここに私の問題があります、
- フロント サーバー (apache または nginx) があり、proxy_pass "iamurl/server_render/" から "backend.iamurl.com:3000/" のような構成がいくつかありました。
- 「backend.iamurl.com:3000」サーバーで実行されているサーバーレンダリングreact-routerプログラムがあります。(react、react-router、koa2、redux)。
- クライアント側で実行すると、すべてが正しくなります。
- サーバー側で実行すると、初回はサーバー(koa2)でのリクエストで、ctx.url=/を取得するのでルーターが一致しました。しかし、renderToString() が終了し、クライアントが応答を受信したとき、location.path は「/server_render」であるため、react-router は必要なものをレンダリングしません。
問題はクライアント側とサーバー側で異なるパスであることは知っていますが、この状況(プロキシを使用)は大企業では非常に一般的だと思います。ブラウザがサーバーのレンダリング応答を受信したときに正しく実行するにはどうすればよいですか?
みんなのアイデア募集中です。
my routes コード (クライアント側とサーバー側で共有)
<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()
}
}