提交ajax请求时,如何“搁置”原始请求?在满足条件之前暂时使用
When submitting an ajax request, how can you "put the original request on hold" temporarily until a condition is met?
我想实现一个recaptcha过程,捕获所有ajax请求之前,他们通过-所需的过程将如下:
- 用户完成一个操作,该操作将引起某种ajax请求。
- 如果用户已经完成了验证码过程,ajax请求将不再延迟,继续执行
- 如果用户还没有完成验证码过程,暂时搁置ajax请求,直到验证码过程完成,然后继续ajax请求。
我已经得到的东西的状态,我拦截呼叫,但我不知道如何把它暂时搁置。以下是相关代码:
<script>
var captchaValidated = null;
var currentRequests = [];
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
if (options.url != "/ValidateCaptcha") {
if (captchaValidated == null || captchaValidated == false) {
if (captchaValidated == null){
openRecaptcha();
} else {
verifyCaptcha(); //see async question in method
}
if (!captchaValidated) {
jqXHR.abort();
} else {
//let the original request proceed now - but how?!
}
}
}
});
function verifyCaptcha() {
var grecaptcha = $("g-recaptcha-response");
var encodedResponse;
if (grecaptcha != null) {
encodedResponse = grecaptcha.val();
$.ajax({
async: false, //set to false so that the calling method completes rather than async - what do you think?
headers: headers,
cache: false,
url: "/ValidateCaptcha",
type: 'POST',
contentType: 'application/json',
success: function (data) {
//parse the data - did we get back true?
captchaValidated = data;
},
error: function (raw, textStatus, errorThrown) { captchaValidated = null; alert("Validate ReCaptcha Error: " + JSON.stringify(raw)); },
data: JSON.stringify({ "encodedResponse": encodedResponse })
});
}
}
function invalidateCaptcha(){
captchaValidated = null;
}
function openRecaptcha() {
grecaptcha.render('recaptcha', {
'sitekey': "thekey",
'callback': verifyCaptcha,
'expired-callback': invalidateCaptcha,
'type': 'audio image'
});
$("#recaptchaModal").modal('show');
}
</script>
如何进行的任何建议将不胜感激,提前感谢!
感谢@Loading和@guest271314为我指出正确的方向,帮助我把事情弄清楚。我把我是如何完成它的贴在下面——也许它会对其他人有所帮助。当然,如果有人想参与我的实施,请参与。
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCaptcha&render=explicit&hl=en" async defer></script>
<script>
var captchaValidated = null;
var currentRequests = [];
var captchaPrompted = false;
var captchaReady = false;
var resetCaptcha = false;
function onloadCaptcha() {
captchaReady = true;
captcha = grecaptcha.render('recaptcha', {
'sitekey': '<yoursitekey>',
'callback': verifyCaptcha,
'expired-callback': invalidateCaptcha,
'type': 'audio image'
});
}
var deferredCaptcha = null;
var promiseCaptcha = null;
var captcha = null;
function openRecaptcha() {
if (!captchaReady) {
setTimeout(openRecaptcha, 50);
}
if (captchaPrompted) {
return;
}
captchaPrompted = true;
var captchaTimer = setInterval(function () {
if (captchaValidated != null) {
if (captchaValidated) {
deferredCaptcha.resolve();
} else {
deferredCaptcha.reject();
captchaValidated = null;
}
}
}, 100);
if (resetCaptcha) {
captcha.reset();
}
deferredCaptcha = $.Deferred();
promiseCaptcha = deferredCaptcha.promise();
promiseCaptcha.done(function () {
//captcha was successful
clearInterval(captchaTimer);
//process the queue if there's items to go through
if (currentRequests.length > 0) {
for (var i = 0; i < currentRequests.length; i++) {
//re-request the item
$.ajax(currentRequests[i]);
}
}
});
promiseCaptcha.fail(function () {
//captcha failed
clearInterval(captchaTimer);
currentRequests = []; //clear the queue
});
$("#recaptchaModal").modal('show');
}
function verifyCaptcha() {
resetCaptcha = true;
var response = $("#g-recaptcha-response").val();
var encodedResponse;
// confirm its validity at the server end
$.ajax({
headers: headers,
cache: false,
url: "/ValidateCaptcha",
type: 'POST',
contentType: 'application/json',
success: function (data) {
captchaValidated = data;
if (!data) {
captchaPrompted = false;
}
},
error: function (raw, textStatus, errorThrown) { captchaValidated = false; captchaPrompted = false; alert("WTF Validate ReCaptcha Error?!: " + JSON.stringify(raw)); },
data: JSON.stringify({ "encodedResponse": response })
});
}
function invalidateCaptcha(){
deferredCaptcha.reject();
captchaValidated = null;
resetCaptcha = true;
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (settings.url == '/ValidateCaptcha' || captchaValidated) {
// we're validating the captcha server side now or it's already been validated - let it through
} else {
if (typeof settings.nested === 'undefined'){
settings.nested = true; //this flag is to determine whether it's already in the queue
currentRequests.push(settings); //add the request to the queue to be resubmitted
//prompt them with the captcha
openRecaptcha();
}
return false; // cancel this request
}
}
});
</script>
在$.ajaxPrefilter()
用.then()
链接openCaptcha
呼叫verifyCaptcha
if (captchaValidated == null){
openRecaptcha().then(verifyCaptcha);
}
在verifyCaptcha
使用.is()
带参数"*"
检查document
中是否存在一个元素
if (grecaptcha.is("*")) {
在openRecaptcha()
,如果grecaptcha.render
不返回异步结果返回jQuery承诺对象使用.promise()
;else链到grecaptcha.render
和$("#recaptchaModal").modal('show')
;使用$.when()
return $("#recaptchaModal").modal('show').promise()
或
return $.when(grecaptcha.render(/* parameters */)
, $("#recaptchaModal").modal('show').promise())
像这样?(伪代码)
verified = false;
$('#myButton').click(function(){
if (!verified) verify_by_captcha();
if (verified){
$.ajax(function(){
type: 'post',
url: 'path/to/ajax.php',
data: your_data
})
.done(function(recd){
//ajax completed, do what you need to do next
alert(recd);
});
}
});//end myButton.click
相关文章:
- 通过js在新选项卡中有条件地打开url
- ajax请求的顺序总是不同的
- 我已经创建了一个jquery转盘,并使用if条件来运行和停止转盘
- Meteor如何接收HTTP请求
- 根据条件线性执行请求
- 修复在执行http获取请求angularJS时的竞争条件
- 如果满足条件,则发送 ajax GET 请求
- 使JQuery ajax请求成为有条件的
- 避免向服务器发出有条件的请求
- 这对AJAX请求是竞争条件吗?
- 包含和条件与传统的多文件请求
- 提交ajax请求时,如何“搁置”原始请求?在满足条件之前暂时使用
- Angularjs:请求数据之前的一个条件
- Ajax请求和竞赛条件(客户端和服务器端)
- 在特定条件下重新触发GET请求
- 三元操作符条件永远不为真,尝试多行ajax请求
- 猫鼬查找具有多个条件的记录并检查请求参数是否为空
- NPM请求库的错误条件
- 如何从递归请求中返回promise,并在数据匹配条件时进行解析
- HTTP 请求条件