NodeJS React + Express + Serve静态尾随Slash

bzzcjhmw  于 2023-04-05  发布在  Node.js
关注(0)|答案(1)|浏览(96)

这是一个业余爱好项目,所以我试图保存成本并运行所有的一台服务器。在开发机器上,我在端口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/,然后它再次工作,但是我更愿意一起去掉/
有什么明显的东西我错过了吗?

pexxcrt2

pexxcrt21#

当使用serveStatic路由到特定路由时,它将尝试在所选文件夹中查找文件夹,因此在本例中,它将尝试在您的build文件夹中查找名为page的文件夹,当路由到一个文件夹时,它搜索一个index.html文件,这就是基本路由/工作而其他路由不工作的原因。React-router为你处理路由,所以你只需要为它提供index.html

router.get('*', (req, res) => { 
    res.sendFile(pathToIndexHtml); 
});

相关问题