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

Express+Node.js环境下Mongoose deleteOne迭代删除获取ID异常问题

方案1:使用路由参数绑定单条记录ID

直接将待删除条目ID写入接口路由,完全避免多个表单隐藏域冲突问题,实现最简单:

  • 前端EJS模板替换原有表单部分代码:
<a href="/admin_panel/delete/<%= recs[i].id %>" onclick="return confirm('确定要删除该内容吗?')">删除</a>
  • 后端新增对应路由接口:
app.get('/admin_panel/delete/:id', isAdm, async (req, res) => {
  await add_joke.deleteOne({id: req.params.id});
  res.redirect('/admin_panel');
})

每个删除按钮对应唯一的路由地址,提交时不会出现ID混淆的问题。


方案2:优化表单实现,确保单表单独立提交

如果要保留POST表单提交的原有逻辑,只需要给每个循环生成的表单增加唯一标识,避免不同表单的字段互相干扰:
EJS模板中的表单部分修改为:

<form action="/admin_panel" method="post" id="delete_form_<%= recs[i].id %>">
  <input type="hidden" name="id_post" value="<%= recs[i].id %>">
  <input type="submit" value="Delete">
</form>

后端原有POST接口无需修改,每个表单提交时只会上传自身内部的隐藏字段值,不会串用其他条目的ID。


方案3:AJAX异步提交(无刷新体验更优)

适合需要更好交互体验的场景,提交删除请求后无需整页刷新,直接移除对应内容节点即可:

  1. EJS模板中替换表单为带自定义属性的按钮:
<button class="delete_btn" data-record-id="<%= recs[i].id %>">删除</button>
  1. 页面新增JS逻辑绑定点击事件:
document.querySelectorAll('.delete_btn').forEach(btn => {
  btn.addEventListener('click', async function() {
    const targetId = this.dataset.recordId;
    if (!confirm('确认删除该条内容?')) return;
    await fetch('/admin_panel', {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: `id_post=${targetId}`
    });
    // 直接移除当前条目的DOM节点
    this.closest('.the_div_of_joke').remove();
  });
})

原有后端POST接口无需修改。


现有问题排查提示

你当前所有请求都返回第一条ID的问题,大概率是MongoDB主键使用错误导致:MongoDB默认生成的主键字段为_id而非id,如果你没有在模型中手动定义id字段并赋值,所有条目的id取值都为undefined,deleteOne操作会默认匹配并删除第一条符合条件的记录,将代码中所有recs[i].id替换为recs[i]._id即可直接解决该问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 13:21:00