Ajax, prevent multiple request on click

前端 未结 10 2179
忘掉有多难
忘掉有多难 2020-11-28 04:10

I\'m trying to prevent multiple requests when user click on login or register button. This is my code, but it doesn\'t work. Just the first time works fine, then return fals

相关标签:
10条回答
  • 2020-11-28 04:44

    This function can help you with control multi Ajax requests and it's has timeout function which can return flag status to 0 after ex. 10sec (In case the server took more than 10 seconds to respond)

    var Request_Controller = function(Request_Name = '', Reactivate_Timeout = 10000)
    {
        var a = this;
        a.Start_Request = function(){
            if(window.Requests == undefined){
                window.Requests = {};
            }
            window.Requests[Request_Name] = {'Status' : 1, 'Time': + new Date()};
        }
    
        a.End_Request = function(){
            if(window.Requests == undefined){
                window.Requests = [];
            }
            window.Requests[Request_Name] = undefined;
        }
    
        a.Is_Request_Running = function(){
            if(window.Requests == undefined || window.Requests[Request_Name] == undefined){
                return 0;
            }else{
                var Time = + new Date();
                // Reactivate the request flag if server take more than 10 sec to respond
                if(window.Requests[Request_Name]['Time'] < (Time - Reactivate_Timeout)) 
                {
                    return 0;
                }else{
                    return 1
                }
            }
        }
    }
    

    To use it:

    var Request_Flag = new Request_Controller('Your_Request_Name');
    if(!Request_Flag.Is_Request_Running()){
    
        Request_Flag.Start_Request();
    
        $.ajax({
            type: "POST",
            url: "/php/auth/login.php",
            data: $("#login-form").serialize(),
            success: function(msg) {
                //stuffs
            },
            complete: function() {
                Request_Flag.End_Request();
            }
        }); 
    }
    
    0 讨论(0)
  • 2020-11-28 04:46

    In your ajax callbacks the context (this) changes from the outer function, you can set it to be the same by using the context property in $.ajax

    $.ajax({
        type: "POST",
        url: "/php/auth/login.php",
        data: $("#login-form").serialize(),
        context: this, //<-----
        success: function(msg) {
            //stuffs
        },
        complete: function() {
            $(this).data('requestRunning', false);
        }
    });      
    
    0 讨论(0)
  • 2020-11-28 04:47

    I found the approach useful. I've implemented it as a general purpose function for jQuery with ES6.

    export default function (button, promise) {
        const $button = $(button);
        const semaphore = 'requestRunning';
    
        if ($button.data(semaphore)) return null;
        $button.data(semaphore, true);
    
        return promise().always(() => {
            $button.data(semaphore, false);
        });
    }
    

    Because $.ajax() returns a promise, you simply pass in the promise and the function takes care of the rest.

    Roughly speaking, here's the usage.

    import preventDoubleClick from './preventdoubleclick';
    
    ...
    
    button.click(() => {
        preventDoubleClick(this, () => $.ajax()
            .done(() => { console.log("success") }));
    });
    
    0 讨论(0)
  • 2020-11-28 04:56

    The problem is here:

        complete: function() {
            $(this).data('requestRunning', false);
        }
    

    this no longer points to the button.

    $('#do-login').click(function(e) {
        var me = $(this);
        e.preventDefault();
    
        if ( me.data('requestRunning') ) {
            return;
        }
    
        me.data('requestRunning', true);
    
        $.ajax({
            type: "POST",
            url: "/php/auth/login.php",
            data: $("#login-form").serialize(),
            success: function(msg) {
                //stuffs
            },
            complete: function() {
                me.data('requestRunning', false);
            }
        });      
    }); 
    
    0 讨论(0)
  • 2020-11-28 04:58

    You can disable the button.

    $(this).prop('disabled', true);
    
    0 讨论(0)
  • 2020-11-28 04:59

    I've tried this and worked very fine for me, I was having trouble that $.ajax send more request until results return,

     var settings = {
        "url": "/php/auth/login.php",
        "method": "POST",
        "timeout": 0,
        "async": false,
        "headers": {
            "Content-Type": "application/json; charset=utf-8"
        },
        "data": jsondata, //data pass here is in JSON format
    };
    $.ajax(settings).done(function (ress) {
      try{
          console.log(ress, "Result from Ajax here");
        }
        catch(error){
          alert(error);
          console.log(ress);
        }
    });
    

    async : false worked for me. Thanks.

    0 讨论(0)
提交回复
热议问题