You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 20:48:18