React.js如何同时支持文件夹式路由与子域名式路由?
兼容两种路由模式的实现方案
1. 先做域名/路径标识提取工具函数
首先需要一个通用工具函数,从当前URL中提取mydomain-name这个核心标识,不管是子域名还是路径前缀模式:
// utils/routeUtils.js export const getDomainIdentifier = () => { const { hostname, pathname } = window.location; const mainDomain = 'dev-pcm.io'; // 你的主域名 // 子域名模式:比如 mydomain-name.dev-pcm.io if (hostname !== mainDomain) { return hostname.split('.')[0]; } // 路径前缀模式:比如 dev-pcm.io/mydomain-name const pathSegments = pathname.split('/').filter(Boolean); if (pathSegments.length > 0) { return pathSegments[0]; } // 直接访问主域名的默认情况 return null; };
2. 适配路由配置
修改路由配置,让每个路由同时支持两种模式的路径匹配:
// routes.js import Home from './pages/Home'; import MyOrders from './pages/MyOrders'; import Auth from './pages/Auth'; import Checkout from './pages/Checkout'; // 生成兼容两种模式的路由路径数组 const generateDualModePaths = (basePath) => { return [ `/:url${basePath}`, // 路径前缀模式(带域名标识前缀) basePath // 子域名模式(无额外前缀) ]; }; export const Routes = [ { path: generateDualModePaths('/'), component: Home, exact: true }, { path: generateDualModePaths('/auth'), component: Auth, exact: true }, { path: generateDualModePaths('/checkout'), component: Checkout, exact: true }, { path: generateDualModePaths('/my-orders'), component: MyOrders, exact: true } ];
3. 优化页面跳转逻辑
不再依赖useParams判断,直接用工具函数获取标识,生成正确跳转路径:
import { useHistory } from "react-router-dom"; import { getDomainIdentifier } from "./utils/routeUtils"; const Button = () => { const history = useHistory(); const goto = () => { const domainId = getDomainIdentifier(); // 仅在路径前缀模式下,才给跳转路径加上域名标识前缀 const targetPath = domainId && window.location.hostname === 'dev-pcm.io' ? `/${domainId}/my-orders` : '/my-orders'; history.push(targetPath); }; return <button onClick={goto}>我的订单页</button>; };
4. 可选:全局路由参数注入
如果需要给所有页面统一传递域名标识,可以在路由渲染时注入:
// App.jsx import { BrowserRouter as Router, Switch, Route } from "react-router-dom"; import { Routes } from "./routes"; import { getDomainIdentifier } from "./utils/routeUtils"; function App() { return ( <Router> <Switch> {Routes.map((route, index) => ( <Route key={index} path={route.path} exact={route.exact} render={(props) => { const domainId = getDomainIdentifier(); // 把域名标识作为props传递给页面组件 return <route.component {...props} domainId={domainId} />; }} /> ))} </Switch> </Router> ); } export default App;
核心逻辑说明
- 通过对比当前域名与主域名,区分子域名/路径前缀模式
- 用工具函数统一生成路由路径,避免重复编写两种模式的路径规则
- 跳转逻辑直接从URL提取标识,不再依赖路由参数,逻辑更稳定可靠
内容的提问来源于stack exchange,提问作者Andaman
相关产品推荐
相关产品推荐

