Fetch API无法向服务器提交数据,请求技术解决方案
问题:Fetch API提交JSON数据后服务器req.body为空的解决方法
我在网站中搭建了聊天室,此前使用表单默认提交将消息数据发送至服务器并存入MongoDB。现在尝试使用Fetch API实现无刷新提交,但以JSON格式提交数据后,服务器无法获取提交的数据。已使用Body Parser解析请求体,但req.body仍为空。相关代码如下:
HTML代码
<form id="form-container"> <input type="text" id="user-name-input" name="userName"> <input required type="text" id="message-input" name="message" placeholder="Send a message here!"> <button type="submit" id="submit-button">Submit</button> </form>
客户端JavaScript代码
submitButton.addEventListener('click', (e) => { e.preventDefault(); var message = document.getElementById('message-input').value; fetch('/dps/chat/request-message-insert', { method: 'POST', body: JSON.stringify({ userName: userName, message: message }), headers: { 'Content-Type': "application/json; charset=UTF-8" } }).then(res => res.json()).then(data => console.log(data)); })
服务器端server.js代码
app.post('/dps/chat/request-message-insert', urlencodedParser, (req, res) => { console.log(req.body) const userName = req.body.userName; const message = req.body.message; client.connect(async (err) => { const collection = client.db("gradilo").collection("chat-messages"); await collection.insertOne({ text: message, userName: userName }) await client.close(); }) })
解决方法
1. 服务器端添加JSON解析中间件
你当前仅使用了urlencodedParser(解析表单application/x-www-form-urlencoded格式数据),但Fetch发送的是application/json格式,需要添加JSON解析中间件才能正确解析请求体:
如果使用Express框架,有两种配置方式:
方式一:全局配置(推荐,所有POST请求都能解析JSON)
在server.js开头添加:
app.use(express.json()); // Express 4.16+内置JSON解析,替代body-parser的json解析 app.use(urlencodedParser); // 保留原urlencoded解析
方式二:仅在该路由使用
修改目标路由:
app.post('/dps/chat/request-message-insert', express.json(), urlencodedParser, (req, res) => { // ... 原有代码 })
2. 修复客户端未定义的userName变量
客户端代码中userName变量未获取输入框的值,导致提交的JSON中userName为undefined,补充获取逻辑:
submitButton.addEventListener('click', (e) => { e.preventDefault(); var userName = document.getElementById('user-name-input').value; // 新增该行获取用户名 var message = document.getElementById('message-input').value; fetch('/dps/chat/request-message-insert', { method: 'POST', body: JSON.stringify({ userName: userName, message: message }), headers: { 'Content-Type': "application/json; charset=UTF-8" } }).then(res => res.json()).then(data => console.log(data)); })
3. 服务器端添加响应并处理错误
当前服务器端未给客户端返回响应,会导致Fetch请求一直处于pending状态,同时需要处理MongoDB连接和插入的错误:
app.post('/dps/chat/request-message-insert', express.json(), urlencodedParser, async (req, res) => { console.log(req.body); const { userName, message } = req.body; try { await client.connect(); // 建议全局初始化MongoDB连接,不要每次请求都创建/关闭 const collection = client.db("gradilo").collection("chat-messages"); await collection.insertOne({ text: message, userName: userName }); res.json({ success: true, msg: "消息保存成功" }); } catch (err) { console.error("保存消息失败:", err); res.status(500).json({ success: false, msg: "保存消息失败" }); } finally { // 注释关闭连接,改为全局复用连接以提升性能 // await client.close(); } })
补充:MongoDB连接建议全局初始化一次,不要每次请求都创建和关闭连接,否则会大幅影响服务性能。
内容的提问来源于stack exchange,提问作者G Jeswin
相关产品推荐
相关产品推荐

