You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 08:54:54