简体   繁体   English

停止ajax请求发布数据,直到收到响应?

[英]Stop an ajax request from posting data until a response is received?

i have written a basic commenting system which is a simple write to database form and it uses ajax as well. 我已经编写了一个基本的注释系统,它是一种简单的数据库形式写操作,它也使用ajax。

The issue is that if i enter my message, and then spam send / the enter key it seems to stack up and then everything is written to the database multiple times. 问题是,如果我输入我的消息,然后发送垃圾邮件/输入回车键,它似乎会堆积起来,然后将所有内容多次写入数据库。

My ajax is like so: 我的ajax就像这样:

$(document).ready(function(){
$(document).on('submit', '.addcomment', function() {
    var $targetForm = $(this);

$.ajax({
type: "POST",
url: "process/addcomment.php",
data: $targetForm.serialize(),
dataType: "json",
success: function(response){
    if (response.databaseSuccess == true) {
        $("#container").load("#container");
        $targetForm.find('#addcommentbutton').attr("disabled", true);
    }
    else {
        $ckEditor.after('<div class="error">Something went wrong!</div>');
    }
}
});

    return false;
    });
});

The submit button does become disabled, but the form can still be entered via the enter keyboard button or even still with a mass spam of the submit button (which is supposed to be disabled) 提交按钮的确被禁用,但是仍然可以通过输入键盘按钮输入表单,甚至仍然带有大量的提交按钮垃圾邮件(应该被禁用)

Is there a way to 100% disable this form with jquery, until the success JSON message is received? 有没有办法在收到成功的JSON消息之前100%使用jquery禁用此表单?

Anymore code just let me know! 只是代码让我知道!

In this case, i would not use delegation. 在这种情况下,我不会使用委托。 I would instead bind the event directly to the form using .one since each form should submit only once (if that's the case.) If you instead only have one addComment form, then i question why you are using delegation in the first place. 我将使用.one将事件直接绑定到表单,因为每个表单仅应提交一次(如果是这种情况。)如果您只拥有一个addComment表单,那么我想问为什么您首先使用委托。

$(commentForm).appendTo(selector).one("submit",function(e){
    e.preventDefault(); // prevent this submit
    $(this).submit(false); // prevent future submits
    // submit data to server

})

Just keep track of if a request is in progress: 只要跟踪请求是否在进行中:

$(document).ready(function(){
  var isSubmitting = false;
  $(document).on('submit', '.addcomment', function() {
    var $targetForm = $(this);
    if (!isSubmitting) {
      isSubmitting = true;
      $.ajax({
         ... 
         success: function(response){
           ...
         },
         complete: function() { isSubmitting = false; }
       });
    }
  });

There are lots of ways to handle this, but the best involves validating the data on the server end. 有很多方法可以解决此问题,但是最好的方法是在服务器端验证数据。 You want to prevent people from overloading the database inadvertently (the "fat finger" problem) or deliberately (the bored script kiddie who decides to crash your server or fill your database with garbage). 您要防止人们无意中(“胖手指”问题)或故意(无聊的脚本小子决定让服务器崩溃或用垃圾填满数据库)使数据库超载。

The best solution: 最佳解决方案:

  • Generate a one-time token when the page is requested (called a "nonce") 请求页面时生成一次性令牌(称为“ nonce”)
  • Post that nonce when you post the data 发布数据时发布该随机数
  • Only accept it on the server side if the nonce has never been used 如果从未使用过随机数,则仅在服务器端接受它

This obviously requires you to keep track of a list of valid nonces, but it prevents any glitches or abuse of the send button. 显然,这需要您跟踪有效的随机数列表,但是它可以防止任何小故障或滥用发送按钮。

Also, as others have pointed out, disable the button much earlier and only run the submit action handler once. 另外,正如其他人指出的那样,请更早地禁用按钮,并且仅运行一次Submit Action处理程序。 That will help with the inadvertent double-clicks and so on, but you also need the nonce to prevent compulsive clickers or intentional misuse. 这将有助于进行无意的双击等操作,但是您还需要使用随机数来防止强迫单击或故意滥用。

Can you do it like below: 你能像下面这样吗?

$(document).ready(function(){
var isAjaxInProgress = null;
$(document).on('submit', '.addcomment', function() {
    var $targetForm = $(this);
    if(isAjaxInProgress === null ||  !$isAjaxInProgress ){
        isAjaxInProgress = true;
        $.ajax({
            type: "POST",
            url: "process/addcomment.php",
            data: $targetForm.serialize(),
            dataType: "json",
            success: function(response){
                if (response.databaseSuccess == true) {
                    $("#container").load("#container");
                    $targetForm.find('#addcommentbutton').attr("disabled", true);
                }
                else {
                    $ckEditor.after('<div class="error">Something went wrong!</div>');
                }
                isAjaxInProgress = false;
            }
        });
    }

    return false;
    });
});

// declare a global ajax request variable //声明一个全局ajax请求变量

var is_request_sent = false;
function send_msg()
{
    if(is_request_sent == false)
    {
        $.ajax({
            type: "POST",
            url: "process/addcomment.php",
            data: $targetForm.serialize(),
            dataType: "json",
            success: function(result){
                //alert(result);
                is_request_sent = false;
           },
            error: function(a,b,c)
            {
                is_request_sent = false;
            },
            beforeSend: function(jqXHR, plain_jqXHR){
                // set request object
                is_request_sent = jqXHR;
                 // Handle the beforeSend event          
            },
            complete: function(){
                // update global request variable
                is_request_sent = false;
             // Handle the complete event
            }
        });
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM