部署MERN应用至Heroku后出现方括号空白页面问题求助
MERN应用部署Heroku后显示空白页面(仅方括号和raw/parsed按钮)
问题详情
本地开发环境(http://localhost:3001)运行正常,部署到Heroku后构建成功无报错,但网站仅显示空白页面,页面上只有一组方括号和两个按钮‘raw’/‘parsed’。已将客户端请求地址从http://localhost:3001/修改为https://songlibrary.herokuapp.com/,问题仍未解决。
相关代码片段
客户端请求示例
useEffect(() => { Axios.get("https://songlibrary.herokuapp.com/").then((response) => { setSongList(response.data) }) }, [])
服务端路由示例
router.get('/', async (req, res) => { Song.find({}, (err, result) => { if (err) { res.send(err) } res.send(result) }) });
数据库连接代码
const mongoose = require('mongoose'); mongoose.connect(process.env.MONGODB_URI || 'mongodb://127.0.0.1:27017/songLibraryDB', { useNewUrlParser: true, useUnifiedTopology: true, }); module.exports = mongoose.connection;
服务端入口文件server/index.js
const express = require('express'); require('dotenv').config(); const db = require('./config/connection'); const cors = require('cors') const app = express() const PORT = process.env.PORT || 3001; app.use(express.urlencoded({ extended: true })); app.use(express.json()); app.use(cors()) app.use(require('./controllers/songRoutes')) db.once('open', () => { app.listen(PORT, () => console.log(`Now listening on localhost: ${PORT}`)); });
项目根目录package.json
{ "name": "songlibrary", "version": "1.0.0", "description": "", "main": "server/index.js", "scripts": { "start": "node server/index.js", "develop": "concurrently \"cd server && npm run watch\" \"cd client && npm start\"", "install": "cd server && npm i && cd ../client && npm i", "seed": "cd server && npm run seed", "build": "cd client && npm run build", "heroku-postbuild": "cd client && npm install --only=dev && npm install && npm run build" }, "engines": { "node": "16.16.0" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "concurrently": "^7.0.0" }, "dependencies": { } }
解决方案
1. 配置静态文件服务与SPA fallback
当前服务器仅挂载了API路由,未配置Express提供React构建后的静态文件。访问根路径时,服务器直接返回API的空数组(方括号),而非前端页面。
修改server/index.js:
const express = require('express'); require('dotenv').config(); const db = require('./config/connection'); const cors = require('cors'); const path = require('path'); // 新增引入path模块 const app = express() const PORT = process.env.PORT || 3001; app.use(express.urlencoded({ extended: true })); app.use(express.json()); app.use(cors()) // 给API路由加前缀,避免与前端路由冲突 app.use('/api', require('./controllers/songRoutes')); // 生产环境下提供静态文件服务 if (process.env.NODE_ENV === 'production') { app.use(express.static(path.join(__dirname, '../client/build'))); // SPA fallback:所有非API请求返回前端index.html app.get('*', (req, res) => { res.sendFile(path.join(__dirname, '../client/build/index.html')); }); } db.once('open', () => { app.listen(PORT, () => console.log(`Now listening on localhost: ${PORT}`)); });
2. 调整API路由路径
修改服务端路由,避免与根路径冲突,例如改为/api/songs:
// songRoutes.js router.get('/songs', async (req, res) => { Song.find({}, (err, result) => { if (err) { res.send(err) } res.send(result) }) });
对应修改客户端请求,使用相对路径避免硬编码:
useEffect(() => { Axios.get("/api/songs").then((response) => { setSongList(response.data) }) }, [])
3. 检查数据库与环境变量
- 在Heroku控制台配置
MONGODB_URI环境变量,指向MongoDB Atlas等生产可用数据库(本地数据库无法在Heroku访问)。 - 执行
heroku logs --tail查看日志,确认数据库连接是否成功、有无其他运行错误。
内容的提问来源于stack exchange,提问作者Brandon Espinosa
相关产品推荐
相关产品推荐

