如何通过AJAX实现从MySQL表及数据库中删除用户
问题:原生JS实现MySQL表格行删除功能失败
我正在构建一个带CRUD功能的MySQL用户表格,用原生JS写代码时遇到问题:点击每行的删除按钮,无法同时从前端表格和数据库中删除对应用户。表格每行代表一个用户,每行都有删除按钮,不知道怎么给每个按钮绑定对应用户并实现删除操作。下面是我的index.js和delete.php代码:
现有代码
index.js
document.addEventListener('DOMContentLoaded', function() { var xhr = new XMLHttpRequest(); xhr.open("GET", "data.php", true); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { var data = JSON.parse(xhr.responseText); if (Array.isArray(data) && data.length === 0) { alert('No record found'); } else { var tableBody = ""; data.forEach(function(row) { tableBody += "<tr>"; tableBody += "<td id='user-id'>" + row.id + "</td>"; tableBody += "<td>" + row.name + "</td>"; tableBody += "<td>" + row.email + "</td>"; tableBody += "<td>" + row.city + "</td>"; tableBody += "<td> <button id='edit' class='btn btn-primary'>Edit</button> <button id='delete' class='btn btn-danger'>Delete</button> </td>" tableBody += "</tr>"; }); document.getElementById("tbody").innerHTML = tableBody; console.warn(xhr.responseText) } } else if (xhr.readyState === 4 && xhr.status !== 200) { alert("An error occurred while fetching the data."); } }; xhr.send(); }); // 提交新用户到数据库 const saveForm = document.querySelector("#save-data"); saveForm.addEventListener('submit', function(e) { e.preventDefault(); // 阻止表单默认提交行为 const modalMess = document.getElementById("response"); const userData = { name: document.querySelector('#name').value, email: document.querySelector('#email').value, city: document.querySelector('#city').value }; const jsonData = JSON.stringify(userData); const xhr = new XMLHttpRequest(); xhr.open('POST', 'adduser.php'); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.onload = function() { if (xhr.status === 200) { modalMess.innerHTML = xhr.responseText console.log(xhr.responseText); } else { console.error('Error: ' + xhr.status); } }; xhr.send(jsonData); }); // 获取所有删除按钮并绑定事件 const deleteButtons = document.querySelectorAll('#delete'); deleteButtons.forEach(function(deleteButton) { deleteButton.addEventListener('click', function() { const userId = this.closest('tr').querySelector('#user-id').textContent; const xhr = new XMLHttpRequest(); xhr.open('POST', 'delete.php'); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.onload = function() { if (xhr.status === 200) { console.log(xhr.responseText); } else { console.error('Error: ' + xhr.status); } }; xhr.send(JSON.stringify({ id: userId })); }); });
delete.php
<?php header('Content-Type:application/json'); header('Access-control-Allow-Origin:*'); header('Access-Control-Allow-Methods:DELETE'); header('Access-Control-Allow-Headers:Acess-Control-Allow-Headers,Content-Type,Acess-Control-Allow-Methods,Authorization,X-Requested-With'); $data = json_decode(file_get_contents("php://input"), true); $student_id = $data['id']; include "connect.php"; $sql = "DELETE FROM clients WHERE id={$student_id}"; if (mysqli_query($conn, $sql)) { echo json_encode(array("message" => "Delete sucessfully", "status" => true)); } else { echo json_encode(array("message" => "not deleted", "status" => false)); } ?>
问题原因及修复方案
1. 重复ID导致DOM选择失败
- 问题:生成表格时,每行的用户ID单元格用了
id='user-id',删除按钮用了id='delete'。ID在DOM中必须唯一,重复ID会导致querySelector只能选中第一个匹配元素。 - 修复:把这些重复ID改成class,比如
class="user-id"和class="delete-btn"。
2. 事件绑定时机错误
- 问题:删除按钮的事件绑定代码在
DOMContentLoaded外面执行,但表格是通过AJAX异步生成的,执行绑定代码时按钮还没渲染到页面上,所以监听器没生效。 - 修复:使用事件委托(给父元素
tbody绑定事件,监听子元素的点击),或者把绑定代码移到表格生成完成的回调里。事件委托更适合动态生成的元素。
3. SQL注入风险
- 问题:PHP中直接把用户传入的ID拼到SQL语句里,存在SQL注入漏洞。
- 修复:使用MySQLi预处理语句,参数化查询。
4. CORS头拼写错误
- 问题:
Acess-Control拼写错误,正确应该是Access-Control,会导致跨域请求失败(如果是跨域场景)。
5. 前端未同步更新表格
- 问题:删除成功后没有移除页面上对应的表格行,用户看不到删除效果。
- 修复:在AJAX的
onload回调中,判断删除成功后,移除当前点击按钮所在的<tr>元素。
修改后的完整代码
index.js
document.addEventListener('DOMContentLoaded', function() { // 加载用户数据生成表格 var xhr = new XMLHttpRequest(); xhr.open("GET", "data.php", true); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { var data = JSON.parse(xhr.responseText); if (Array.isArray(data) && data.length === 0) { alert('No record found'); } else { var tableBody = ""; data.forEach(function(row) { tableBody += "<tr>"; // 把id改成class tableBody += "<td class='user-id'>" + row.id + "</td>"; tableBody += "<td>" + row.name + "</td>"; tableBody += "<td>" + row.email + "</td>"; tableBody += "<td>" + row.city + "</td>"; // 删除按钮用class,新增data-id存储用户ID tableBody += "<td> <button class='btn btn-primary edit-btn'>Edit</button> <button class='btn btn-danger delete-btn' data-id='" + row.id + "'>Delete</button> </td>" tableBody += "</tr>"; }); document.getElementById("tbody").innerHTML = tableBody; } } else if (xhr.readyState === 4 && xhr.status !== 200) { alert("An error occurred while fetching the data."); } }; xhr.send(); // 事件委托:给tbody绑定删除按钮点击事件 document.getElementById('tbody').addEventListener('click', function(e) { if (e.target.classList.contains('delete-btn')) { const deleteBtn = e.target; const userId = deleteBtn.dataset.id; // 直接从data-id获取ID,更高效 const row = deleteBtn.closest('tr'); // 发送删除请求 const xhr = new XMLHttpRequest(); xhr.open('DELETE', 'delete.php'); // 用DELETE方法,和后端设置一致 xhr.setRequestHeader('Content-Type', 'application/json'); xhr.onload = function() { if (xhr.status === 200) { const response = JSON.parse(xhr.responseText); if (response.status) { row.remove(); // 删除成功后移除表格行 alert(response.message); } else { alert('删除失败:' + response.message); } } else { alert('请求失败,状态码:' + xhr.status); } }; xhr.send(JSON.stringify({ id: userId })); } }); }); // 提交新用户到数据库 const saveForm = document.querySelector("#save-data"); saveForm.addEventListener('submit', function(e) { e.preventDefault(); // 阻止表单默认跳转 const modalMess = document.getElementById("response"); const userData = { name: document.querySelector('#name').value, email: document.querySelector('#email').value, city: document.querySelector('#city').value }; const jsonData = JSON.stringify(userData); const xhr = new XMLHttpRequest(); xhr.open('POST', 'adduser.php'); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.onload = function() { if (xhr.status === 200) { modalMess.innerHTML = xhr.responseText; // 提交成功后重新加载表格数据 location.reload(); } else { console.error('Error: ' + xhr.status); modalMess.innerHTML = '提交失败,请重试'; } }; xhr.send(jsonData); });
delete.php
<?php header('Content-Type:application/json'); header('Access-Control-Allow-Origin:*'); header('Access-Control-Allow-Methods:DELETE'); // 修正拼写错误 header('Access-Control-Allow-Headers:Access-Control-Allow-Headers,Content-Type,Access-Control-Allow-Methods,Authorization,X-Requested-With'); $data = json_decode(file_get_contents("php://input"), true); // 检查ID是否存在 if(!isset($data['id']) || empty($data['id'])){ echo json_encode(array("message" => "缺少用户ID", "status" => false)); exit; } $student_id = $data['id']; include "connect.php"; // 使用预处理语句防止SQL注入 $sql = "DELETE FROM clients WHERE id = ?"; $stmt = mysqli_prepare($conn, $sql); mysqli_stmt_bind_param($stmt, "i", $student_id); // i表示整数类型 if (mysqli_stmt_execute($stmt)) { // 检查是否有行被影响 if(mysqli_stmt_affected_rows($stmt) > 0){ echo json_encode(array("message" => "删除成功", "status" => true)); }else{ echo json_encode(array("message" => "未找到该用户", "status" => false)); } } else { echo json_encode(array("message" => "删除失败:".mysqli_error($conn), "status" => false)); } // 关闭语句和连接 mysqli_stmt_close($stmt); mysqli_close($conn); ?>
内容的提问来源于stack exchange,提问作者Zach Delapenha
相关产品推荐
相关产品推荐

