这是一个业余爱好项目,所以我试图保存成本并运行所有的一台服务器。在开发机器上,我在端口3000上启动Express.js,并在端口3001上启动CRA,并在CRA的package.json中使用"proxy": "http://localhost:3000",
,生活很好。
前端是基本的CRA项目,有自己的路由器
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/whatever" element={<Whatever />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
后端是Express.js和express router,想法是/
服务于构建的CRA应用程序,然后检查API路由,最后如果无法匹配任何内容,后端将返回CRA应用程序并让CRA的路由器弄清楚发生了什么。
import express from 'express';
import path from 'path';
import serveStatic from 'serve-static';
const router = express.Router(),
root = path.join(__dirname, '..', '..');
const frontendPublicPath = path.join(root, '..', 'frontend', 'build');
router.use('/', serveStatic(frontendPublicPath));
router.use('/api/user', (req, res) => res.json(req.socket.remoteAddress));
router.use('/api/admin/esi/fetch', ensureAuthenticated, admin.fetchEndpoints);
router.use('/api/admin/esi/update', ensureAuthenticated, admin.updateEndpoints);
router.use('*', serveStatic(frontendPublicPath));
app.use('/', router);
这个设置工作起来很有魅力,但有一个问题:在生产服务器(heroku)上,它构建静态前端并将其提供给客户端,然而,存在尾随斜杠问题
如果直接请求https://example.org
,则得到https://example.org
如果您直接请求httts://example.org/page
,则会得到https://example.org/page/
和301重定向
如果您直接请求https://example.org
,则会得到https://example.org
,如果您随后使用页面上的链接转到httts://example.org/page
,则会得到httts://example.org/page
,因为在这种情况下路由由CRA单独完成,并且没有后端请求。
在localhost上,此重定向从未发生
我正在试图弄清楚如何摆脱此设置中的301重定向。
尝试的事情:
将express.Router()
更改为express.Router({ strict: true })
在这里似乎没有任何作用,因为正如预期的那样,重定向来自serveStatic
变化
router.use('/', serveStatic(frontendPublicPath, { redirect: false }));
...
router.use('*', serveStatic(frontendPublicPath, { redirect: false }));
它在localhost上按预期工作。然而,在生产上,我只能访问https://example.org
,然后按预期在CRA内导航,但任何深层链接都失败。不再有301重定向,但要求httts://example.org/page
会说Cannot GET /page
,这是出乎意料的,因为我会假设它会失败所有的路由,直到它击中*
路由,只是服务CRA应用程序?如果我请求httts://example.org/page/
,然后它再次工作,但是我更愿意一起去掉/
。
有什么明显的东西我错过了吗?
1条答案
按热度按时间pexxcrt21#
当使用
serveStatic
路由到特定路由时,它将尝试在所选文件夹中查找文件夹,因此在本例中,它将尝试在您的build
文件夹中查找名为page
的文件夹,当路由到一个文件夹时,它搜索一个index.html
文件,这就是基本路由/
工作而其他路由不工作的原因。React-router
为你处理路由,所以你只需要为它提供index.html
。