我正在尝试在用户点击登录或注册按钮时阻止多个请求。这是我的代码,但它不起作用。只是第一次工作正常,然后返回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);
}
});
});
有什么想法吗?谢谢!
答案 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页面上的。它将阻止所有多重请求。 :)