ASP.Net Core MVC中SweetAlert删除确认失效问题排查
问题根因
- 没有给删除按钮绑定确认逻辑:当前删除按钮是普通
<a>超链接,点击后会直接发起GET请求跳转到后端Delete接口,你写的confirm()函数根本没有被触发。你看到的弹窗一闪而过,是页面开始跳转卸载前JS做的最后渲染,页面马上就会跳走,自然等不到用户点击确认。 - HTML id重复:
foreach循环里给每一行删除按钮都加了id="delete",HTML要求id全局唯一,重复id会导致JS选元素时只能匹配到第一个按钮,其他按钮的事件完全绑定不上。 - 函数命名冲突:自定义函数名
confirm和浏览器原生的window.confirm弹窗方法重名,会产生覆盖冲突,导致函数执行异常。 - 确认后没有执行删除动作:就算弹窗正常弹出,你写的逻辑在用户点确认后只弹了个“deleted”的提示,根本没有发起请求到后端,数据根本删不掉。
- 接口设计有安全风险:删除操作走GET请求不符合HTTP规范,搜索引擎爬虫、浏览器预加载、用户误点链接都会直接触发数据删除,也没有做CSRF防护,很容易被恶意攻击。
修复方案
1. 改造后端Delete接口
把原来的GET删除接口改成POST请求,增加防伪令牌校验,避免非法请求:
[HttpPost] [ValidateAntiForgeryToken] public IActionResult Delete(int id) { var category = _unitOfWork.categoryRepo.Get(x => x.Id == id); if (category == null) { return NotFound(); } _unitOfWork.categoryRepo.Delete(category); _unitOfWork.Save(); TempData["SuccessMsg"] = "分类已成功删除"; return RedirectToAction("Index"); }
原来的GET版本Delete方法建议直接删除,避免被恶意调用直接删数据
2. 调整列表页删除按钮
去掉重复的id,用class标记所有删除按钮,把删除地址和防伪令牌存在按钮的自定义属性上,把超链接改成普通按钮更符合操作语义:
首先在视图顶部引入防伪令牌服务,生成令牌:
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery @{ var csrfToken = Antiforgery.GetAndStoreTokens(Context).RequestToken; }
然后修改循环内的删除列代码:
<td> <button type="button" class="btn btn-danger delete-btn" data-url="@Url.Action("Delete", "Category", new { id = item.Id })" data-token="@csrfToken"> Sil </button> </td>
3. 重写前端交互逻辑
换掉冲突的函数名,在DOM加载完成后给所有删除按钮绑定点击事件,先阻止默认跳转,弹出确认框,等用户确认后再动态提交POST表单执行删除,同时支持页面返回后弹出删除成功提示:
<script> $(function () { // 绑定删除按钮点击事件 $('.delete-btn').click(function (e) { e.preventDefault(); const targetUrl = $(this).data('url'); const token = $(this).data('token'); swal({ title: "确认删除?", text: "删除后数据无法恢复,请确认操作", icon: "warning", buttons: ["取消", "确认删除"], dangerMode: true }).then(confirmed => { if (confirmed) { // 动态构建表单提交POST请求,携带防伪令牌 const deleteForm = $('<form>', { method: 'post', action: targetUrl }); deleteForm.append($('<input>', { type: 'hidden', name: '__RequestVerificationToken', value: token })); $('body').append(deleteForm); deleteForm.submit(); } }) }) // 页面加载时显示后端传递的操作成功提示 @if (TempData["SuccessMsg"] != null) { <text> swal("操作成功", "@TempData["SuccessMsg"]", "success"); </text> } }) </script>
改完之后即可实现预期效果:点击删除按钮先弹出SweetAlert确认框,点取消就关闭弹窗不做任何操作,点确认才会提交请求删除数据,删完跳回列表页弹出成功提示。
内容的提问来源于stack exchange,提问作者İbrahim Özdemir
相关产品推荐
相关产品推荐

