Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
548 views
in Technique[技术] by (71.8m points)

javascript - jquery $.ajax posts multiple times (one extra after each subsequent submit)

On my forgot password form, the jquery ajax post is fired multiple times (one more after each submit). So if the user enters an invalid email 3 times, and then a valid email, the user gets 4 password-changed emails. Seems like the event gets stacked each time an error is thrown, and all of them get fired on the next submit. Here's all my relevant code. What am I doing wrong?

JS

 RetrievePassword = function () {
        var $popup = $("#fancybox-outer");
        var form = $popup.find("form");
        form.submit(function (e) {
            var data = form.serialize();
            var url = form.attr('action');
            $.ajax({
                type: "POST",
                url: url,
                data: data,
                dataType: "json",
                success: function (response) {
                    ShowMessageBar(response.Message);
                    $.fancybox.close()
                },
                error: function (xhr, status, error) {
                    ShowMessageBar(xhr.statusText);
                }
            });
            return false;
        });    
    };

MVC CONTROLLER/ACTION

[HandlerErrorWithAjaxFilter, HttpPost]
        public ActionResult RetrievePassword(string email)
        {
            User user = _userRepository.GetByEmail(email);

            if (user == null)
                throw new ClientException("The email you entered does not exist in our system.  Please enter the email address you used to sign up.");

            string randomString = SecurityHelper.GenerateRandomString();
            user.Password = SecurityHelper.GetMD5Bytes(randomString);
            _userRepository.Save();

            EmailHelper.SendPasswordByEmail(randomString);

            if (Request.IsAjaxRequest())
                return Json(new JsonAuth { Success = true, Message = "Your password was reset successfully. We've emailed you your new password.", ReturnUrl = "/Home/" });
            else
                return View();           
        }

HandlerErrorWithAjaxFilter

public class HandleErrorWithAjaxFilter : HandleErrorAttribute
    {
        public bool ShowStackTraceIfNotDebug { get; set; }
        public string ErrorMessage { get; set; }

        public override void OnException(ExceptionContext filterContext)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                var content = ShowStackTraceIfNotDebug || filterContext.HttpContext.IsDebuggingEnabled ? filterContext.Exception.StackTrace : string.Empty;
                filterContext.Result = new ContentResult
                {
                    ContentType = "text/plain",
                    Content = content
                };

                string message = string.Empty;
                if (!filterContext.Controller.ViewData.ModelState.IsValid)
                    message = GetModeStateErrorMessage(filterContext);
                else if (filterContext.Exception is ClientException)
                    message = filterContext.Exception.Message.Replace("
", " ").Replace("
", " ");
                else if (!string.IsNullOrEmpty(ErrorMessage))
                    message = ErrorMessage;
                else
                    message = "An error occured while attemting to perform the last action.  Sorry for the inconvenience.";

                filterContext.HttpContext.Response.Status = "500 " + message;
                filterContext.ExceptionHandled = true;
                filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
            }
            else
            {
                base.OnException(filterContext);
            }
        }

        private string GetModeStateErrorMessage(ExceptionContext filterContext)
        {
            string errorMessage = string.Empty;
            foreach (var key in filterContext.Controller.ViewData.ModelState.Keys)
            {
                var error = filterContext.Controller.ViewData.ModelState[key].Errors.FirstOrDefault();
                if (error != null)
                {
                    if (string.IsNullOrEmpty(errorMessage))
                        errorMessage = error.ErrorMessage;
                    else
                        errorMessage = string.Format("{0}, {1}", errorMessage, error.ErrorMessage);
                }
            }

            return errorMessage;
        }

    }

Here's more JS. I'm using the fancybox plugin as my lightbox. The Retrieve Password link is on the login lightbox.

$(document).ready(function () {

    $(".login").fancybox({
        'hideOnContentClick': false,
        'titleShow': false,
        'onComplete': function () {       

            $("#signup").fancybox({
                'hideOnContentClick': false,
                'titleShow':false,
                'onComplete': function () {

                }
            });

            $("#retrievepassword").fancybox({
                'hideOnContentClick': false,
                'titleShow': false,
                'onComplete': function () {

                }
            });
        }
    });  

});
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'm not a jQuery expert, but it would appear to me that every time fancybox onComplete fires , you add (another) event handler to #retrievepassword and #signup... I'm missing the rest of the html in the page, so i dont know if/when the login dialog content is loaded, but the following might work better:

$(document).ready(function () {

    $(".login").fancybox({
        'hideOnContentClick': false,
        'titleShow': false,
        'onComplete': function () {       

        }
    }); 

    $("#signup").fancybox({
        'hideOnContentClick': false,
        'titleShow':false,
        'onComplete': function () {

        }
    });

    $("#retrievepassword").fancybox({
        'hideOnContentClick': false,
        'titleShow': false,
        'onComplete': function () {

         }
    });
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...