react SPA 中的深层链接正确回退到 index.html;但之后不会导航回深层链接

时间:2021-02-01 08:28:02

标签: reactjs apache mod-rewrite react-router fallback

我在子目录下的 apache2.4 网络服务器上托管了一个 CRA (v4) 反应应用程序“TheProject”:

/htdocs/site/TheProject

我在这个位置定义了一个 .htaccess 文件:(并启用了 mod 重写插件!)

RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]

# If the requested resource doesn't exist, use index.html
RewriteRule ^ index.html

为了处理我的客户端路由,我使用的是 react-router (5.2.0),我的路由配置如下所示:

<BrowserRouter basename='site/TheProject'>
<Route exact path="/history" component={History}/>
<Route exact path="/dashboard" component={Dashboard}/>
<Route exact path="/">
   <Redirect to="/dashboard" />
</Route>
<BrowserRouter basename={baseName}>

我将根请求重定向到我的仪表板组件,并使用 site/TheProject 作为基本名称, 因此 URL 将按如下方式提供:www.thehost.com/site/TheProject/[routing]

预期行为:

网络服务器上的现有资源: (1)

thehost.com/site/theproject/xyz => thehost.com/site/theproject/xyz

网络服务器上不存在的资源: (2)

thehost.com/site/theproject/xyz/fpfze => thehost.com/site/theproject/index.html => thehost.com/site/theproject/dashboard

在服务器上不存在,但存在客户端反应路由: (3)

thehost.com/site/theproject/history => thehost.com/site/theproject/index.html => thehost.com/site/theproject/history

我现在面临的问题是 (3) 没有按预期工作:对 /history?q=something 的请求将由我的 apache 配置处理,并将回退到我的index.html 钩子,但它不会按预期重定向回 /history?q=something,而是重定向回 /dashboard

但要注意的一件更有趣的事情是,当网络选项卡打开时,请求会被处理到 /history?q=somethingAPI 请求执行该 History 组件中的 do,这意味着访问了 History 组件中的 useEffect 钩子!

1 个答案:

答案 0 :(得分:0)

答案在于 react-router 是如何工作的,它来自以 angular 声明路由的静态方式,react-router 通过“动态”声明路由来工作

https://reactrouter.com/web/guides/philosophy

<BrowserRouter basename='site/TheProject'>
<Route exact path="/history" component={History}/>
<Route exact path="/dashboard" component={Dashboard}/>
<Route exact path="/">
   <Redirect to="/dashboard" />
</Route>

改为:

<BrowserRouter basename='site/TheProject'>
   <Switch>
       <Route exact path="/" component={Dashboard}/>
       <Route exact path="/history" component={History}/>
       <Route exact path="/dashboard" component={Dashboard}/>
       <Redirect to='/' />
   </Switch>

其中 switch 只采用以下列表中仅 1 条路由的第一个匹配项,按声明顺序。