前端FormData提交至Express后端,req.body为空问题求助
问题:Express后端无法接收FormData转换的JSON数据
前端表单代码
return ( <div className='contentDiv'> <Container> <Form onSubmit={getFormData}> <Form.Group className="mb-3" controlId="formBasicName"> <Row><Form.Control name="id" type="number" value={3} readOnly={ true }></Form.Control></Row> <Row> <Col> <Form.Label>Forname:</Form.Label> <Form.Control name="firstname" type="text" placeholder="navn"></Form.Control> </Col> <Col> <Form.Label>Efternavn:</Form.Label> <Form.Control name="lastname" type="text" placeholder="Efternavn"></Form.Control> </Col> </Row> </Form.Group> <Row><Button type="submit">Create user</Button></Row> </Form> </Container> </div> )
表单提交函数
const getFormData = async (event) => { const data = new FormData(event.currentTarget); event.preventDefault(); await fetch(`/api/newMember`, { method: 'POST', headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }) .then(res => { console.log(res); }) .catch(err => { console.log(err) }) };
客户端验证结果
客户端遍历FormData时能正确输出数据:
id 3 firstname Lucky lastname Luke
后端接口代码
const express = require('express'); const knex = require('knex'); const cors = require('cors'); const bodyParser = require('body-parser'); const app = express(); const port = 3001; app.post('/api/newMember', (req, resp) => { const { id, firstname, lastname } = req.body; console.log(req.body); const newMember = { id: id, firstname: firstname, lastname: lastname, }; db('members').insert(newMember) .then(res => { resp.send(res) }) .catch(err => { console.log(err); return; }) }) app.listen(port, () => { console.log('Server listening on port: ' + port); });
问题现象
后端执行console.log(req.body)时输出{},但将请求体替换为JSON.stringify({firstname: 'Test'})时,后端能正常接收数据,确认问题出在JSON.stringify(data)的转换上。
解决方法
FormData是特殊的键值对集合,无法直接被JSON.stringify序列化,需要先转换为普通JavaScript对象,再进行JSON序列化。
修改后的提交函数:
const getFormData = async (event) => { const data = new FormData(event.currentTarget); event.preventDefault(); // 将FormData转换为普通对象 const formDataObj = Object.fromEntries(data.entries()); // 把id从字符串转回数字(FormData会将所有值转为字符串) formDataObj.id = parseInt(formDataObj.id, 10); await fetch(`/api/newMember`, { method: 'POST', headers: { "Content-Type": "application/json" }, body: JSON.stringify(formDataObj) }) .then(res => { console.log(res); }) .catch(err => { console.log(err) }) };
同时,后端需要确保配置了解析JSON请求体的中间件,在app.post之前添加:
// 使用express内置的JSON解析中间件 app.use(express.json()); // 或者使用body-parser // app.use(bodyParser.json());
原理说明
JSON.stringify无法处理FormData对象,直接转换会得到空对象{},因为FormData的内部结构不被JSON序列化机制识别。Object.fromEntries(data.entries())可以将FormData的键值对迭代器转换为普通对象,这样就能正常被JSON序列化。- FormData会把所有表单值转为字符串类型,因此需要手动将id字段转回数字,与前端表单的类型匹配。
内容的提问来源于stack exchange,提问作者user1960836
相关产品推荐
相关产品推荐

