Node.js中点击博客删除按钮报错,for循环访问元素返回undefined
Node.js无刷新删除博客报错问题排查与解决
问题描述
我是Node.js初学者,制作了blogs.ejs页面展示登录用户的博客文章,添加删除锚点以实现无刷新删除功能,使用fetch向后端发送POST请求。但每次点击删除按钮都会报错,控制台无输出,排查发现for循环中访问元素时每次返回undefined,不清楚问题所在。
相关代码
blogs.ejs代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="/css/home.css" /> </head> <body> <div class="flex-box"> <div class="nav-content"> Welcome <%= user.name %></div> <div></div> <div></div> <div class="nav-content"><a href="/home/<%= user._id %>">Home</a></div> <div class="nav-content"><a href="/myblogs/<%= user._id %>">My blogs</a></div> <div class="nav-content"><a href="/addblogs/<%= user._id %>">Add blog</a></div> </div> <br> <div> <p class="user_id" style="display:none"><%= user._id %></p> <h2 class="blog-name">My Blogs</h2> </div> <br> <% if(blogs.length!=0){ %> <% blogs.forEach(blog=>{ %> <div class="blog-content"> <div class="blog"> <a class="delete" data-doc="<%= blog._id %>">Delete</a> <p class="id" style="display:none ;"><%= blog._id %></p> <h3><%= blog.title %></h3> <p><%= blog.post %></p> </div> </div> <br><br> <% }) %> <% }else{%> <h3>No blog Posts</h3> <% } %> <br><br> </div> <script> const deleted =document.querySelectorAll('a.delete'); for(var i=0;i<deleted.length;i++){ deleted[i].addEventListener('click',function(){ // Accessing post id var id=document.getElementsByClassName('id')[i].innerHTML; const usr_id=document.getElementsByClassName('user_id')[0].innerHTML; console.log("In script tag: post id is "+id) const url='/delete'; customHeaders = { "Content-Type": "application/json", } let data={ post_id:id, usr_id:usr_id }; fetch(url,{ method:'POST', body:JSON.stringify(data), headers:customHeaders, }).then((res) =>{ res.json(); console.log("Method passed") }) .then((data)=>{ console.log(data); }) .catch((err) => console.log(err)) }) } </script> </body> </html>
routes.js代码
router.post('/delete',async(req,res)=>{ const id=req.body.id; const user=req.body.usr_id; console.log("In routes.js: post id is "+id); try{ await Post.deleteOne({_id:id}); console.log("deleted"); res.json({redirect:'/'}) } catch(err){ console.log(err); } })
问题分析与解决
1. 循环变量作用域导致undefined
用var声明的i是函数级作用域,循环结束后i的值会变成deleted.length,点击事件触发时,document.getElementsByClassName('id')[i]访问超出数组长度的索引,直接返回undefined。
解决方式:
- 把
var i改成let i,let是块级作用域,每次循环会创建独立的变量:
for(let i=0;i<deleted.length;i++){ // 原逻辑保留 }
- 或者用
forEach遍历删除按钮,写法更简洁:
deleted.forEach(btn => { btn.addEventListener('click', function() { // 后续逻辑 }) })
2. 简化博客ID获取逻辑
你已经给删除按钮加了data-doc="<%= blog._id %>"属性,直接通过按钮自身就能拿到ID,不用再查找同级的.id元素:
const id = this.getAttribute('data-doc');
3. 修复后端参数接收错误
前端发送的参数是post_id,但后端代码里取的是req.body.id,导致后端拿到的id是undefined。修改后端代码:
const id = req.body.post_id; // 改为匹配前端的参数名
4. 补全fetch的then链返回值
第一个then里调用res.json()但没有返回,导致第二个then接收的data是undefined,需要加上return:
.then((res) =>{ console.log("Method passed") return res.json(); // 返回解析后的JSON数据 })
修改后的完整代码示例
前端脚本修改版
const deleted = document.querySelectorAll('a.delete'); deleted.forEach(btn => { btn.addEventListener('click', function() { const id = this.getAttribute('data-doc'); const usr_id = document.getElementsByClassName('user_id')[0].innerHTML; console.log("In script tag: post id is " + id); const url = '/delete'; const customHeaders = { "Content-Type": "application/json", } let data = { post_id: id, usr_id: usr_id }; fetch(url, { method: 'POST', body: JSON.stringify(data), headers: customHeaders, }).then((res) => { console.log("Method passed") return res.json(); }) .then((data) => { console.log(data); // 删除成功后移除页面上对应的博客元素 this.closest('.blog-content').remove(); }) .catch((err) => { console.log(err); }) }) })
后端代码修改版
router.post('/delete', async(req, res) => { const id = req.body.post_id; // 修正参数名 const user = req.body.usr_id; console.log("In routes.js: post id is " + id); try { await Post.deleteOne({ _id: id }); console.log("deleted"); res.json({ redirect: '/', success: true }) } catch (err) { console.log(err); res.status(500).json({ error: err.message }); // 向前端返回错误信息 } })
内容的提问来源于stack exchange,提问作者Athul
相关产品推荐
相关产品推荐

