如何让JavaScript获取待删除帖子的索引值以实现精准删除功能?
如何让JavaScript获取待删除帖子的索引值以实现精准删除功能?
看起来你现在卡在了「把帖子的索引传给后端、然后正确删除对应内容」这一步,我来帮你梳理下问题和修复方案~
首先先指出你当前代码里的几个小问题:
- HTML 原生表单不支持直接用
method="DELETE",浏览器只会识别GET和POST两种方法,所以你写的method="DELETE"其实不会生效,后端的app.delete("/delete")根本接不到请求。 - 你的提交按钮写了
name=index,但没给它设置value,所以后端拿不到当前帖子的索引值;而且用按钮传索引不如用隐藏输入框更规范。 - 后端的删除路由逻辑完全搞反啦——你现在是在往数组里新增数据,而不是删除😅
下面给你两种可行的修复方案,你可以根据需求选:
方案一:用表单 + method-override 模拟 DELETE 请求(适合不需要无刷新的场景)
这种方法是 Express 里处理 RESTful 风格请求的常用方式,需要借助 method-override 中间件来让表单支持 DELETE/PUT 这类方法。
第一步:修正 EJS 模板的表单
把索引通过隐藏输入框传给后端,同时加上模拟 DELETE 方法的隐藏字段:
<% if (locals.ptit) { %> <% for (let index = 1 ; index < ptit.length; index++) { %> <div class="post"> <h1><%= ptit[index] %></h1> <p><%= stuff[index] %></p> <form action="/delete" method="POST"> <!-- 隐藏字段存储当前帖子的索引 --> <input type="hidden" name="postIndex" value="<%= index %>"> <!-- 告诉后端这是一个模拟的 DELETE 请求 --> <input type="hidden" name="_method" value="DELETE"> <input type="submit" value="POST IS DONE" class="donebtn"> </form> </div> <% } %> <% } %>
第二步:配置 method-override 中间件
先在项目里安装这个中间件:
npm install method-override
然后在你的 Express 入口文件(比如 app.js)里引入并使用:
const express = require('express'); const methodOverride = require('method-override'); const app = express(); // 配置中间件,识别表单里的 _method 字段 app.use(methodOverride('_method')); // 别忘了配置解析表单数据的中间件! app.use(express.urlencoded({ extended: true }));
第三步:修正后端的 DELETE 路由逻辑
现在要根据接收到的索引,从数组里删除对应元素,而不是新增:
app.delete("/delete", (req, res) => { // 把表单传过来的索引转成数字 const postIndex = parseInt(req.body.postIndex); // 先检查索引是否有效,避免数组越界 if (!isNaN(postIndex) && postIndex >= 0 && postIndex < titles.length) { // splice(索引, 要删除的个数) 用来删除数组指定位置的元素 titles.splice(postIndex, 1); posts.splice(postIndex, 1); } // 重新渲染博客页面,传更新后的数组 res.render("blog.ejs", { ptit: titles, stuff: posts, }); });
方案二:用 Fetch API 发送无刷新 DELETE 请求(更流畅)
如果想要点击按钮后不刷新页面就删除帖子,可以用前端 JS 发送 AJAX 请求,体验更好。
第一步:修改 EJS 模板,给按钮加索引数据
把表单换成普通按钮,用 data-index 属性存储当前帖子的索引:
<% if (locals.ptit) { %> <% for (let index = 1 ; index < ptit.length; index++) { %> <div class="post"> <h1><%= ptit[index] %></h1> <p><%= stuff[index] %></p> <button class="donebtn" data-index="<%= index %>">POST IS DONE</button> </div> <% } %> <% } %>
第二步:添加前端点击事件(可以放在 EJS 的 <script> 里,或者单独的 JS 文件)
给每个删除按钮绑定点击事件,用 Fetch 发送 DELETE 请求:
// 给所有删除按钮绑定事件 document.querySelectorAll('.donebtn').forEach(btn => { btn.addEventListener('click', async function() { // 从按钮的 data-index 属性拿到索引 const postIndex = this.dataset.index; try { // 发送 DELETE 请求到带索引的路由 await fetch(`/delete/${postIndex}`, { method: 'DELETE' }); // 删除成功后,可以直接移除页面上的帖子元素,不用刷新 this.closest('.post').remove(); } catch (error) { console.log('删除失败:', error); } }); });
第三步:修改后端路由为带参数的形式
现在路由从 URL 里取索引,处理后返回成功状态:
app.delete("/delete/:index", (req, res) => { const postIndex = parseInt(req.params.index); if (!isNaN(postIndex) && postIndex >= 0 && postIndex < titles.length) { titles.splice(postIndex, 1); posts.splice(postIndex, 1); } // 因为是 AJAX 请求,返回 JSON 告知前端成功即可 res.json({ success: true }); });
两种方案都能解决你的问题,方案一更简单,适合入门;方案二更流畅,用户体验更好~
备注:内容来源于stack exchange,提问作者Siffrin
相关产品推荐
相关产品推荐

