MERN Stack部署Heroku后POST请求无值问题求助
看起来你已经搞定了ServiceWorker的提示弹窗,但核心的POST数据丢失问题还在,结合你的代码和Heroku日志情况,我整理了几个关键排查点和修复方案:
1. 修复Express静态文件服务配置(同时解决404和路由混乱)
你的server.js里静态文件服务的写法有明显问题:
// 错误写法:express.static指向单个HTML文件 app.use(express.static(path.join(__dirname, '../react-ui/public/index.html')));
express.static的作用是托管静态资源目录,不是单个文件。这种写法会导致service-worker.js、.map这类静态文件找不到(也就是日志里的404),甚至可能干扰API路由的正常解析。改成下面的配置:
// 正确配置:托管public目录下所有静态资源 app.use(express.static(path.join(__dirname, '../react-ui/public'))); // 处理SPA路由:所有非API的GET请求返回index.html(避免页面刷新后404) app.get('*', (req, res) => { res.sendFile(path.join(__dirname, '../react-ui/public/index.html')); });
这个改动既能解决静态资源的404问题,也能保证SPA的路由正常工作,不会让API请求被静态文件规则拦截。
2. 阻止表单默认提交行为(前端请求被中断的核心原因)
看你的App.js代码,你是在form标签里触发的fetch请求,但如果没有阻止表单的默认提交行为,浏览器会自动以传统方式提交表单(直接刷新页面),导致你的fetch请求还没完成就被中断,后端自然收不到任何数据。
修改你的提交函数,一定要加上e.preventDefault():
handleSubmit = (e) => { e.preventDefault(); // 必须添加这行!阻止表单默认的刷新提交 alert("word = "+ this.state.word); // 这里能拿到值说明state没问题 fetch("/api/words",{ method:"POST", headers: { 'Accept': 'application/json, text/plain, */*', 'Content-Type':'application/json' }, body:JSON.stringify({ "word":this.state.word, "definition":this.state.definition, "sound":this.state.audioRecorded }) }) .then((res) => res.json()) .then((data) => console.log(data)) }
同时确保你的form标签正确绑定了这个函数:
<form onSubmit={this.handleSubmit}> <!-- 表单输入项 --> </form>
3. 验证后端Body解析和路由
虽然你已经用了bodyParser.json(),但可以做两个小验证确保没问题:
- 确认
bodyParser.json()在API路由之前被注册(你的代码里已经做到了,这点没问题) - 在
router.js的POST路由里添加日志,查看req.body的实际内容:
// router.js里的POST /words路由 router.post('/words', (req, res) => { console.log("Received request body:", req.body); // 去Heroku日志里看这个输出 // 后续数据库操作逻辑... });
如果Heroku日志里这个打印是空对象,说明请求的Content-Type头有问题,或者前端没有正确发送JSON格式的body。可以在前端fetch里再次确认Content-Type确实是application/json,也可以在后端额外添加express.urlencoded({ extended: true })作为 fallback(不过你用的是JSON格式,主要还是确保前端请求头正确)。
4. 额外检查:Heroku构建脚本和环境变量
- 确认Heroku上的
MONGOLAB_URI环境变量正确设置(虽然这和POST body为空无关,但数据库连接失败会导致后续操作报错) - 如果你的前端是用create-react-app搭建的,要确保
package.json里有正确的Heroku构建脚本:
"scripts": { "start": "node server.js", "heroku-postbuild": "cd react-ui && npm install && npm run build" }
这种情况下,静态文件路径要改成../react-ui/build,因为create-react-app构建后的文件会放在build目录下。
把这些修改完成后重新部署到Heroku,查看日志应该就能解决POST body为空的问题,同时静态资源的404也会消失。
内容的提问来源于stack exchange,提问作者Diagathe Josué

