You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SSR中获取react-router-redux的<Redirect>跳转URL?

解决react-router-redux@5.0.0-alpha.9 SSR中捕获跳转的问题

我完全懂你遇到的这个痛点——在服务端渲染场景下,<Redirect>的跳转只在浏览器端生效,服务端根本抓不到这个跳转动作,没法主动发起302重定向。那个版本的ConnectedRouter确实没有像StaticRouter那样内置context参数,但我们可以利用react-router-redux和Redux Store的联动特性来解决这个问题。

核心思路

react-router-redux会把所有路由操作(包括<Redirect>触发的跳转)转换成Redux Action,同步更新Store里的路由状态。所以我们只需要在服务端渲染完成后,对比Store中的路由状态和初始请求URL,就能判断是否发生了跳转,进而提取目标URL。

具体实现步骤

1. 初始化Memory History和Redux Store

首先创建服务端专用的Memory History,再初始化带路由中间件的Redux Store,确保路由状态能和Store同步:

import { ConnectedRouter, routerMiddleware } from 'react-router-redux';
import createHistory from 'history/createMemoryHistory';
import { Provider } from 'react-redux';
import { renderToString } from 'react-dom/server';
import { createStore, applyMiddleware } from 'redux';
import rootReducer from './reducers'; // 你的根reducer

// 基于当前请求URL初始化Memory History
const history = createMemoryHistory({
  initialEntries: [req.url],
  initialIndex: 0,
});

// 创建包含路由中间件的Store,初始路由状态和请求URL保持一致
const store = createStore(
  rootReducer,
  { router: { location: history.location, action: 'POP' } },
  applyMiddleware(routerMiddleware(history))
);

2. 渲染组件并检查跳转状态

同步渲染完成后,直接对比Store中的路由URL和初始请求URL,不一致就说明发生了<Redirect>跳转:

// 把组件渲染成HTML字符串
const appHtml = renderToString(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <Application />
    </ConnectedRouter>
  </Provider>
);

// 从Store中取出当前路由状态
const { router } = store.getState();
const currentRouteUrl = router.location.pathname + router.location.search;

// 判断是否发生了跳转
if (currentRouteUrl !== req.url) {
  // 发起302重定向到目标URL
  res.writeHead(302, { Location: currentRouteUrl });
  res.end();
  return;
}

// 没有跳转的话,返回渲染好的页面
res.send(`
  <!DOCTYPE html>
  <html>
    <head>
      <title>SSR App</title>
    </head>
    <body>
      <div id="root">${appHtml}</div>
      <!-- 加载客户端脚本完成hydration -->
      <script src="/client-bundle.js"></script>
    </body>
  </html>
`);

为什么history.listen没触发?

在SSR的同步渲染流程里,react-router-redux是通过Redux中间件同步History和Store状态的,history.listen的回调不会在同步渲染过程中触发(History的更新逻辑是绑定在Redux Action的处理流程里的),所以直接监听Store状态才是最可靠的方式。

额外注意事项

  • 确保你的认证逻辑能在服务端执行:比如判断用户是否登录的逻辑要在SSR阶段运行,这样<Redirect>才会在服务端渲染时被触发。
  • 不管<Redirect>用的是push还是默认的replace,我们只需要对比URL即可,不需要区分动作类型。
  • 初始Store的router状态要和请求URL严格一致,避免出现误判。

内容的提问来源于stack exchange,提问作者Sergio Toro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:40:46