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);
}
});
});
Любые идеи? Спасибо!
Ответы
Ответ 1
Проблема здесь:
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);
}
});
});
Ответ 2
Используйте 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
});
});
Ответ 3
Вы можете отключить кнопку.
$(this).prop('disabled', true);
Ответ 4
В ваших обратных вызовах ajax контекст (this
) изменяется от внешней функции, вы можете установить его таким же, используя свойство context в $.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);
}
});
Ответ 5
Или вы можете сделать это нажатием $(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.
Ответ 6
Я нашел подход полезным. Я реализовал его как функцию общего назначения для jQuery с 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);
});
}
Поскольку $.ajax()
возвращает обещание, вы просто передаете обещание, и функция позаботится об остальном.
Грубо говоря, здесь использование.
import preventDoubleClick from './preventdoubleclick';
...
button.click(() => {
preventDoubleClick(this, () => $.ajax()
.done(() => { console.log("success") }));
});
Ответ 7
Эта функция может помочь вам управлять несколькими Ajax-запросами и имеет функцию тайм-аута, которая может возвращать статус флага в 0 после ex. 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();
}
});
}
Ответ 8
Я также столкнулся с подобной проблемой.
Просто добавьте $('#do-login').attr("disabled", true);
дает мне решение.
$('#do-login').click(function(e) {
e.preventDefault();
$('#do-login').attr("disabled", true);
.........
.........
Здесь do-login
это идентификатор кнопки.
Ответ 9
для предотвращения множественного запроса ajax на всем сайте. Например: Если вы используете ajax-запрос на другой странице ajax, используя ajax в php-цикле и т.д., Дайте вам несколько запросов ajax с одним результатом. У меня есть решение:
Use window.onload = function() { ... }
вместо
$(document).ready(function(){ ... });
на главной странице index.php. Его будет предотвращать все запросы.:)