我使用React Router 4.0和Express 4.14来创建一个混合了单页面应用程序(SPA)和多页面应用程序(MPA)的应用程序。我不知道这是不是很好,但这不是重点。我实际上是为了学习而不是真实的应用程序。这个想法来自于您在应用程序内部强烈分隔的部分,例如博客和投资组合。
因此,当我想要导航为SPA时,我会使用Link
中的react-router-dom
组件,例如<Link to="/reactrouter-route">
。如果我想对服务器处理的路由发出请求,请使用<a href="/server-route">
。
我有一个中间件记录了我的服务器收到的任何请求的路径。我定义了两条路线,每条路线都提供完整的SPA。为了与博客/投资组合示例保持一致,想象一下我有以下
const express = require('express');
const app = express();
app.use((req, res, next) => {
console.log(req.path);
next();
});
app.get('/', (req, res) => {
res.sendFile('blog.html');
});
app.get('/portfolio', (req, res) => {
res.sendFile('portfolio.html');
});
当我转到/
时,博客会作为SPA加载,我可以根据需要转到导航回/
的不同帖子。一切都按预期工作。 SPA内的所有导航都由React Router管理,服务器只收到/
的第一个请求。
想象一下,从一个特定的帖子,比如/posts/some-post
,我有一个指向投资组合的链接。如果我点击它,我会在服务器上收到请求,并以组合SPA的形式响应。我可以在组合SPA中导航,但我不能回到/posts/some-post
。我收到以下错误:
无法获取/发布/发布帖子
我认为错误是由服务器抛出的,但令人惊讶的是我回去时没有得到任何请求。我只通过链接在服务器上收到请求(仅限<a>
)。
我一直在做测试,如果我从/portfolio
回到/
则没有问题。这可以按预期工作。
我在服务器中定义了一条路径,其路由与我在React Router路由中的规则相同。我在这条新路线中匹配的路径是/posts/:postid
。我将此路线设置为重定向到/
。现在,如果我从posts/some-post
转到/portfolio
并尝试回来,我会收到同样的错误。这并不奇怪,因为服务器没有收到请求。如果我通过在浏览器中输入网址直接转到/
,我就会/posts/some-post
正常。
但是,一旦我手动转到/posts/some-post
,我就可以从/portfolio
返回/posts/some-post
而不会出错。现在它的行为就像服务器被调用一样。实际上,我在服务器中获取了一个获取静态文件的请求。但是,我没有收到/posts/some-post
或/
的请求。
即便如此,如果从/posts/some-other-post
转到/portfolio
并尝试返回,我会收到错误。
我想这与缓存有关,但我不知道那里发生了什么。 React Router处理何时返回?什么时候服务器handlin呢?缓存如何参与此过程?
答案 0 :(得分:0)
听起来您需要在SPA中更清楚地了解服务器和客户端角色的心理模型。 “单页”是重要的一部分。
使用React构建的客户端永远不应该从服务器加载页面。它应该是一个“单页”。换句话说,您根本不应在客户端应用中使用<a href="/server-route">
。客户端应该只使用fetch
(https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)之类的内容从服务器获取(JSON)数据。
我强烈建议您查看Create React App,其中还介绍了integrate with a node API backend在开发过程中的操作方法。基本上,您希望所有客户端路由都是/post/:postid
,它将由React Router处理,然后React组件将使用fetch
从/api/posts/10
之类的数据中获取数据。如果您使用/api
将所有请求作为前缀添加到服务器,则应该有助于您的心理模型。