Ajax,防止点击多个请求

时间:2013-09-12 22:41:54

标签: javascript jquery ajax

我正在尝试在用户点击登录或注册按钮时阻止多个请求。这是我的代码,但它不起作用。只是第一次工作正常,然后返回false ..

$('#do-login').click(function(e) {
    e.preventDefault();

    if ( $(this).data('requestRunning') ) {
        return;
    }

    $(this).data('requestRunning', true);

    $.ajax({
        type: "POST",
        url: "/php/auth/login.php",
        data: $("#login-form").serialize(),
        success: function(msg) {
            //stuffs
        },
        complete: function() {
            $(this).data('requestRunning', false);
        }
    });      
}); 

有什么想法吗?谢谢!

10 个答案:

答案 0 :(得分:50)

问题在于:

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

this不再指向该按钮。

$('#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);
        }
    });      
}); 

答案 1 :(得分:41)

使用on()off(),这就是他们的目的:

$('#do-login').on('click', login);

function login(e) {
    e.preventDefault();
    var that = $(this);
    that.off('click'); // remove handler
    $.ajax({
        type: "POST",
        url: "/php/auth/login.php",
        data: $("#login-form").serialize()
    }).done(function(msg) {
        // do stuff
    }).always(function() {
        that.on('click', login); // add handler back after ajax
    });
}); 

答案 2 :(得分:5)

您可以停用该按钮。

$(this).prop('disabled', true);

答案 3 :(得分:3)

在ajax回调中,上下文(this)从外部函数更改,您可以使用$ .ajax中的context属性将其设置为相同

$.ajax({
    type: "POST",
    url: "/php/auth/login.php",
    data: $("#login-form").serialize(),
    context: this, //<-----
    success: function(msg) {
        //stuffs
    },
    complete: function() {
        $(this).data('requestRunning', false);
    }
});      

答案 4 :(得分:0)

或者您可以通过 $(this).addClass("disabled");按钮或链接进行操作,点击完成后,您可以 $(this).removeClass("disabled");

// CSS

.disabled{
cursor: not-allowed;

}

// JQUERY

$('#do-login').click(function(e) {
   e.preventDefault();

    $(this).addClass("disabled");
    $.ajax({
        type: "POST",
        url: "/php/auth/login.php",
        data: $("#login-form").serialize(),
        context: this,
        success: function(msg) {
    //do more here

           $(this).removeClass("disabled");
        },
    });
});

P.S。如果使用bootstrap css,则不需要css部分。

答案 5 :(得分:0)

我发现这种方法很有用。我已经将它实现为带有ES6的jQuery的通用函数。

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);
    });
}

因为$.ajax()返回一个promise,你只需传入promise,而函数将处理其余的事情。

粗略地说,这就是用法。

import preventDoubleClick from './preventdoubleclick';

...

button.click(() => {
    preventDoubleClick(this, () => $.ajax()
        .done(() => { console.log("success") }));
});

答案 6 :(得分:0)

此功能可以帮助您控制多个Ajax请求,并且具有超时功能,可以在ex之后将标志状态返回0。 10秒(如果服务器响应时间超过10秒)

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
            }
        }
    }
}

要使用它:

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();
        }
    }); 
}

答案 7 :(得分:0)

我也遇到了类似的问题。

只需添加$('#do-login').attr("disabled", true);即可找到解决方案。

$('#do-login').click(function(e) {
   e.preventDefault();
   $('#do-login').attr("disabled", true);
   .........
   .........

do-login是按钮ID。

答案 8 :(得分:0)

我已经尝试过了,并且对我来说工作得很好,但是在$ .ajax发送更多请求直到结果返回之前,我遇到了麻烦,

#include <array>
#include <boost/hana/fwd/optional.hpp>
#include <boost/hana/optional.hpp>
#include <string>
#include <utility>
#include <vector>

template <int N, typename T1, typename T2, typename ...Ts>
struct Recursive
    : std::pair<std::array<T1, N>, 
                boost::hana::optional<std::vector<Recursive<N, T2, Ts...>>>> {};

template <int N, typename T>
struct Recursive<N, T> : std::array<T, N> {};

template<typename ...T>
using Recursive2 = Recursive<2u, T...>;

template<typename ...T>
using Recursive3 = Recursive<3u, T...>;

int main() {
    using boost::hana::nothing;
    Recursive2<int> x(std::make_pair(std::array<int, 2>{0,0}, nothing));
}

#include <iostream> template <int N, typename T, typename ...Ts> struct Recursive { void operator()(){ std::cout << "general\n"; } }; template <int N, typename T> struct Recursive<N, T> { void operator()(){ std::cout << "specialized\n"; } }; template<typename ...T> using Recursive2 = Recursive<2u, T...>; template<typename ...T> using Recursive3 = Recursive<3u, T...>; int main() { Recursive2<int>{}(); Recursive2<int>{}(); Recursive2<int,int>{}(); } 为我工作。 谢谢。

答案 9 :(得分:-9)

用于防止整个站点中的多个ajax请求。例如:如果在其他ajax页面中使用ajax请求,在php循环中使用ajax等,请为您提供多个ajax请求,其中包含一个结果。我有解决方案:

Use window.onload = function() { ...  } 

而不是

$(document).ready(function(){ ...  });
主要的index.php页面上的

。它将阻止所有多重请求。 :)

相关问题