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

MERN栈开发问卷时MongoDB无法持续存数据,仅重启Express服务器可保存

问题根本原因

你遇到的写入中断问题主要由以下几个错误共同导致:

  1. 前端异步请求未等待完成就跳转页面,大量未完成请求被浏览器强制取消
  2. 后端接口处理完数据库操作后未返回响应,导致请求长期挂起,占满浏览器的并发请求配额后后续请求全部卡住
  3. 数据库更新逻辑错误,全量覆盖字段且多余的分支逻辑容易生成无效数据
  4. 未配置MongoDB连接自动重连,连接意外中断后所有数据库操作都会失败
修复方案

前端代码修改

// 1. handleSubmit改为异步,等待请求完成再跳转,添加错误捕获
async function handleSubmit(e) {
  e.preventDefault();
  localStorage.setItem("name", input);

  const data = {
    uuid: localStorage.getItem("uuid"),
    name: localStorage.getItem("name"),
  };

  try {
    // 等待请求返回再跳转
    await axios.post("/answers", data);
    history.push("/next-question");
  } catch (err) {
    console.error("提交失败", err);
    // 可自行添加提交失败的用户提示
  }
}

// 2. 修复input value绑定错误,你之前写的value={value}是未定义变量,要改成对应state
<input id="name" type="text" value={input} onChange={handleChange} />

后端代码修改

// 1. 配置mongoose自动重连,添加连接错误监听
mongoose.connect(process.env.MONGO_URI, {
  autoReconnect: true,
  serverSelectionTimeoutMS: 5000
}).catch(err => console.log('Mongo连接失败', err));

mongoose.connection.on('error', err => {
  console.log('Mongo连接错误', err);
});

// 2. 完全重写/answers接口逻辑,删除冗余分支,每次操作后返回响应
app.post("/answers", async (req, res) => {
  const { uuid } = req.body;
  if (!uuid) {
    return res.status(400).json({error: "缺少uuid参数"});
  }
  try {
    // 只用传过来的字段更新,不覆盖其他已存字段,开upsert自动新建不存在的文档
    await Answer.updateOne(
      { uuid },
      { $set: req.body },
      { upsert: true }
    );
    // 必须返回响应,不能让请求挂起
    res.json({ success: true });
  } catch (err) {
    console.log("更新失败", err);
    res.status(400).json({error: "更新失败: " + err.message});
  }
});
可选优化
  • 点击下一题后禁用按钮,避免用户重复点击发送重复请求
  • 累计3-5道题批量提交一次答案,减少请求频次
  • 前端定期同步localStorage未提交的答案,防止数据丢失

内容的提问来源于stack exchange,提问作者Marina Kim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 10:00:05