简体   繁体   English

Ajax,防止点击多个请求

[英]Ajax, prevent multiple request on click

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 false..第一次工作正常,然后返回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);
        }
    });      
}); 

Any ideas?有任何想法吗? Thanks!谢谢!

The problem is here:问题在这里:

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

this no longer points to the button. 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);
        }
    });      
}); 

Use on() and off() , that's what they are there for :使用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
    });
}); 

您可以禁用该按钮。

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

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 回调中,上下文( this )从外部函数更改,您可以使用 $.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);
    }
});      

I have also faced a similar problem.我也遇到过类似的问题。

Just adding $('#do-login').attr("disabled", true);只需添加$('#do-login').attr("disabled", true); gives me the solution.给我解决方案。

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

Here do-login is button id.这里do-login是按钮 id。

I've tried this and worked very fine for me, I was having trouble that $.ajax send more request until results return,我已经尝试过这个并且对我来说效果很好,我遇到了 $.ajax 发送更多请求直到结果返回的问题,

 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. async : false对我async : false Thanks.谢谢。

Or you can do it by $(this).addClass("disabled");或者你可以通过$(this).addClass("disabled"); to you button or link and after click is performed, you can $(this).removeClass("disabled");到你的按钮或链接,点击执行后,你可以$(this).removeClass("disabled"); . .

// CSS // 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");
        },
    });
});

PS If you use bootstrap css, you do not need the css part. PS 如果使用 bootstrap css,则不需要 css 部分。

I found the approach useful.我发现这种方法很有用。 I've implemented it as a general purpose function for jQuery with ES6.我已经将它实现为带有 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);
    });
}

Because $.ajax() returns a promise, you simply pass in the promise and the function takes care of the rest.因为$.ajax()返回一个 promise,你只需传入 promise,剩下的就交给函数了。

Roughly speaking, here's the usage.粗略地说,这是用法。

import preventDoubleClick from './preventdoubleclick';

...

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

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.此功能可以帮助您控制多个 Ajax 请求,并且它具有超时功能,可以在 ex 之后将标志状态返回到 0。 10sec (In case the server took more than 10 seconds to respond) 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
            }
        }
    }
}

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

for prevent multiple ajax request in whole site.防止在整个站点中出现多个 ajax 请求。 For example: If use ajax request in other ajax page, Using ajax in php loop, etc, Give you multiple ajax request with one result.例如:如果在其他ajax页面中使用ajax请求,在php循环中使用ajax等,给你多个ajax请求一个结果。 I have solution:我有解决方案:

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

instead of代替

$(document).ready(function(){ ...  });

on the main index.php page.在 index.php 主页面上。 Its will be prevent all multi request.它会阻止所有的多请求。 :) :)

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

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