ASP.NET MVC中重复点击提交按钮致Sweet Alert提示重复显示问题
问题:Ajax提交表单时Sweet Alert提示重复显示
开发ASP.NET MVC应用,采用Ajax提交表单,多次点击提交按钮时,Sweet Alert的"Employee Exist Before"提示会重复显示——第二次点击弹出两次,第三次点击弹出三次。已尝试提交时禁用按钮,但问题未解决。
相关代码
原前端代码
$("#ResignationApp").submit(function (e) { e.preventDefault(); var formData = $(this).serialize(); console.log("data is" + formData) $.ajax({ type: "POST", dataType: 'json', url: '@Url.Action("RequesterIndex", "Resignation")', data: formData, success: function (response) { for (let item of response) { if (item.Key === "success") { success = item.Value; } if (item.Key === "message") { message = item.Value; } } if (success) { Swal.fire({ icon: 'success', title: 'Submition Request', text: message }).then((result) => { if (result.isConfirmed) { var url = '@Url.Action("IndexResignation", "Home")' + '?filenumber=' + empidval; window.open(url, '_self'); } }); } else { Swal.fire({ icon: 'error', title: 'Resignation Submission Form', text: 'Employee Exist Before' }); return false; } }, error: function (error) { var url = '@Url.Action("UnauthorizedUser", "Home")' + '?filenumber=' + empidval; window.open(url, '_self'); } }); });
后端代码
[HttpPost] public JsonResult RequesterIndex(ResignationRequester resignationRequester) { dynamic responseData = new ExpandoObject(); responseData.success = false; responseData.message = ""; var filenumber = resignationRequester.EmpID; if (Session[SessionKeys.UserCode] != null) { JDEUtility jde = new JDEUtility(); if (ModelState.IsValid) { int checkEmployeeNoExist = jde.CheckEmployeeExistOrNot(resignationRequester.EmpID); if (checkEmployeeNoExist >= 1) { responseData.success = false; responseData.message = "Employee Exist Before"; return Json(responseData); } try { Workforce.InsertToReignation(resignationRequester, JoinedDate, (string)Session[SessionKeys.Username], (DateTime)Session[SessionKeys.LastWorkingDate], noticeperiod, (int)Session[SessionKeys.UserCode]); } catch (Exception ex) { responseData.success = false; responseData.message = "Create Not Done Correctly"; return Json(responseData); } if (string.IsNullOrEmpty(ViewBag.errorMsg)) { responseData.success = true; responseData.message = "Resignation Submission form Created successfully"; return Json(responseData); } } else { responseData.success = false; var errors = ModelState.Select(x => x.Value.Errors) .Where(y => y.Count > 0) .ToList(); responseData.message = "Some Required Fields Not Added"; return Json(responseData); } } else { responseData.success = false; responseData.message = "No Data For This File No"; return Json(responseData); } return Json(responseData); }
修改后(尝试禁用按钮)的前端代码
const $submitBtn = $('#btnsubmit'); $("#ResignationApp").submit(function (e) { e.preventDefault(); $submitBtn.prop('disabled', true); var formData = $(this).serialize(); console.log("data is" + formData) $.ajax({ type: "POST", dataType: 'json', url: '@Url.Action("RequesterIndex", "Resignation")', data: formData, success: function (response) { for (let item of response) { if (item.Key === "success") { success = item.Value; } if (item.Key === "message") { message = item.Value; } } if (success) { Swal.fire({ icon: 'success', title: 'Submition Request', text: message }).then((result) => { if (result.isConfirmed) { var url = '@Url.Action("IndexResignation", "Home")' + '?filenumber=' + empidval; window.open(url, '_self'); } }); } else { if (message === "Employee Exist Before") { Swal.fire({ icon: 'error', title: 'Resignation Submission Form', text: 'Employee Exist Before' }); return false; } else { Swal.fire({ icon: 'error', title: 'Resignation Submission Form', text: message }); return false; } } console.log("errorMsg is" + errorMsg); }, error: function (error) { var url = '@Url.Action("UnauthorizedUser", "Home")' + '?filenumber=' + empidval; window.open(url, '_self'); } }).always(() => { $submitBtn.prop('disabled', false); }); });
问题原因
核心原因是表单的submit事件被多次绑定:
- 可能是页面存在局部刷新(比如Ajax加载内容后重新执行脚本),或者脚本被重复引用(比如布局页和视图页都加载了同一段绑定事件的代码),导致每次加载都会给表单添加一个新的
submit事件处理器。 - 当点击提交按钮时,所有已绑定的事件处理器都会触发,每个处理器都会发起Ajax请求并在响应后弹出提示,所以出现多次提示的情况。
- 禁用按钮只能阻止后续的点击操作,但已经绑定的事件处理器会在之前的请求完成后继续执行,因此无法解决重复提示的问题。
解决方案
方案1:绑定事件前先解绑,确保只有一个处理器
在绑定submit事件前,先调用off('submit')移除已存在的事件绑定,避免重复绑定:
const $submitBtn = $('#btnsubmit'); // 先解绑所有submit事件,再绑定新的 $("#ResignationApp").off('submit').on('submit', function (e) { e.preventDefault(); if ($submitBtn.prop('disabled')) return; // 防止重复提交 $submitBtn.prop('disabled', true); var formData = $(this).serialize(); console.log("data is" + formData) $.ajax({ type: "POST", dataType: 'json', url: '@Url.Action("RequesterIndex", "Resignation")', data: formData, success: function (response) { let success = false; let message = ""; // 声明局部变量,避免全局变量污染 for (let item of response) { if (item.Key === "success") { success = item.Value; } if (item.Key === "message") { message = item.Value; } } if (success) { Swal.fire({ icon: 'success', title: 'Submission Request', text: message }).then((result) => { if (result.isConfirmed) { var url = '@Url.Action("IndexResignation", "Home")' + '?filenumber=' + empidval; window.open(url, '_self'); } }); } else { Swal.fire({ icon: 'error', title: 'Resignation Submission Form', text: message || 'Employee Exist Before' }); } }, error: function (error) { var url = '@Url.Action("UnauthorizedUser", "Home")' + '?filenumber=' + empidval; window.open(url, '_self'); } }).always(() => { $submitBtn.prop('disabled', false); }); });
方案2:添加提交状态标记,阻止重复请求
定义一个变量标记当前是否正在提交,在提交前检查状态,避免重复发起请求:
let isSubmitting = false; const $submitBtn = $('#btnsubmit'); $("#ResignationApp").submit(function (e) { e.preventDefault(); if (isSubmitting) return; // 如果正在提交,直接返回 isSubmitting = true; $submitBtn.prop('disabled', true); var formData = $(this).serialize(); console.log("data is" + formData) $.ajax({ type: "POST", dataType: 'json', url: '@Url.Action("RequesterIndex", "Resignation")', data: formData, success: function (response) { let success = false; let message = ""; for (let item of response) { if (item.Key === "success") { success = item.Value; } if (item.Key === "message") { message = item.Value; } } if (success) { Swal.fire({ icon: 'success', title: 'Submission Request', text: message }).then((result) => { if (result.isConfirmed) { var url = '@Url.Action("IndexResignation", "Home")' + '?filenumber=' + empidval; window.open(url, '_self'); } }); } else { Swal.fire({ icon: 'error', title: 'Resignation Submission Form', text: message || 'Employee Exist Before' }); } }, error: function (error) { var url = '@Url.Action("UnauthorizedUser", "Home")' + '?filenumber=' + empidval; window.open(url, '_self'); }, complete: function() { isSubmitting = false; $submitBtn.prop('disabled', false); } }); });
额外检查项
- 确认脚本是否被重复引用:检查布局页(
_Layout.cshtml)和当前视图页是否都加载了这段绑定事件的脚本,避免重复执行绑定代码。 - 如果页面存在局部刷新(比如用Ajax加载表单区域),确保只在初始加载或刷新后绑定一次事件,或者使用事件委托(绑定到父元素)。
内容的提问来源于stack exchange,提问作者ahmed abdelaziz
相关产品推荐
相关产品推荐

