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异步提交(无刷新体验更优)
适合需要更好交互体验的场景,提交删除请求后无需整页刷新,直接移除对应内容节点即可:
- EJS模板中替换表单为带自定义属性的按钮:
<button class="delete_btn" data-record-id="<%= recs[i].id %>">删除</button>
- 页面新增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
相关产品推荐
相关产品推荐

