MERN应用部署Heroku后页面刷新出现Cannot GET /path问题求助
问题原因与修复方案
你的问题出在路由匹配顺序错误、静态资源路径指向错误,同时catch-all路由的位置导致API请求被拦截。
核心问题分析
- 最初只匹配
/,刷新其他路由时Express找不到对应路由,直接返回404。 - 改成
/*后,所有GET请求(包括API的GET请求)都被返回index.html,导致API失效——因为Express路由是从上到下匹配的,catch-all路由放在API路由前面的话,API请求会先被拦截。 - 另外,你的服务端代码在
server文件夹,原来的path.resolve(__dirname, 'client/build')路径错误,__dirname指向server目录,需要向上一级才能找到同级的client文件夹。
修复步骤
1. 调整路由顺序
把API路由放在生产环境静态资源配置和catch-all路由之前,让Express优先处理API请求,再处理静态资源,最后处理前端路由的刷新请求。
2. 修正静态资源路径
因为server和client是同级文件夹,所以静态资源路径和index.html路径需要调整为../client/build。
修改后的完整app.js核心代码
// 先配置API路由,这一步必须放在最前面 app.use('/api/v1/carers', carerRoutes); app.use('/api/v1/task', taskRoutes); // 生产环境配置 if (process.env.NODE_ENV === 'production') { // 修正静态资源路径:从server目录向上一级找client/build const staticPath = path.resolve(__dirname, '../client/build'); app.use(express.static(staticPath)); // catch-all路由:只处理GET请求,且放在最后 app.get('/*', (req, res) => { const indexPath = path.resolve(__dirname, '../client/build', 'index.html'); res.sendFile(indexPath); }); }
额外验证点
- 确认前端使用的是
BrowserRouter(不是HashRouter),因为HashRouter不需要后端支持,但BrowserRouter必须依赖后端的catch-all配置。 - 部署前先在本地生产环境测试:执行前端的
npm run build命令,然后启动服务端,测试页面刷新和API接口是否正常。
内容的提问来源于stack exchange,提问作者oladimeji
相关产品推荐
相关产品推荐

