Javascript 在提交ajax请求时,您如何;将原始请求搁置”;在满足条件之前暂时停止?

Javascript 在提交ajax请求时,您如何;将原始请求搁置”;在满足条件之前暂时停止?,javascript,jquery,ajax,asynchronous,Javascript,Jquery,Ajax,Asynchronous,我希望实现一个recaptcha过程,在所有ajax请求通过之前捕获它们-所需的过程如下: 用户完成一个操作,该操作将导致某种ajax请求 如果用户已经完成了recaptcha过程,ajax请求将不再延迟 如果用户尚未完成recaptcha过程,则暂时“暂停”ajax请求,直到recaptcha过程完成,然后继续ajax请求 我已经到了截获电话的状态,但我不知道如何暂时暂停。以下是相关代码: <script> var captchaValidated = null;

我希望实现一个recaptcha过程,在所有ajax请求通过之前捕获它们-所需的过程如下:

  • 用户完成一个操作,该操作将导致某种ajax请求
  • 如果用户已经完成了recaptcha过程,ajax请求将不再延迟
  • 如果用户尚未完成recaptcha过程,则暂时“暂停”ajax请求,直到recaptcha过程完成,然后继续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>
    
    
    var captchaValidated=null;
    var currentRequests=[];
    $.ajaxPrefilter(函数(选项、原始选项、jqXHR){
    如果(options.url!=“/ValidateCaptcha”){
    如果(captchaValidated==null | | captchaValidated==false){
    如果(captchaValidated==null){
    openrepatcha();
    }否则{
    verifyCaptcha();//参见方法中的异步问题
    }
    如果(!captchaValidated){
    jqXHR.abort();
    }否则{
    //现在就让最初的请求继续吧-但是怎么做?!
    }
    }
    }
    });
    函数verifyCaptcha(){
    var grecaptcha=$(“g-recaptcha-response”);
    var编码响应;
    if(grecaptcha!=null){
    encodedResponse=grecaptcha.val();
    $.ajax({
    async:false,//设置为false以便调用方法完成而不是异步-您认为如何?
    标题:标题,
    cache:false,
    url:“/ValidateCaptcha”,
    键入:“POST”,
    contentType:'应用程序/json',
    成功:功能(数据){
    //解析数据-我们得到的是真的吗?
    captchaValidated=数据;
    },
    错误:函数(原始、文本状态、错误抛出){captchaValidated=null;警报(“验证ReCaptcha错误:+JSON.stringify(原始));},
    数据:JSON.stringify({“encodedResponse”:encodedResponse})
    });
    }
    }
    函数invalidateCaptcha(){
    captchaValidated=null;
    }
    函数openrepatcha(){
    grecaptcha.render('recaptcha'{
    “sitekey”:“thekey”,
    “回调”:验证验证码,
    “过期回调”:invalidateCaptcha,
    “类型”:“音频图像”
    });
    $(“#recaptchaModal”).modal('show');
    }
    
    任何关于如何进行的建议都将不胜感激,提前感谢

    像这样的?(伪代码)

    verified=false;
    $(“#myButton”)。单击(函数(){
    如果(!验证)通过验证码()验证验证;
    如果(已验证){
    $.ajax(函数(){
    键入:“post”,
    url:'path/to/ajax.php',
    数据:您的_数据
    })
    .完成(功能(记录){
    //ajax完成后,做下一步需要做的事情
    警报(记录);
    });
    }
    });//结束myButton。单击
    $.ajaxPrefilter()
    使用
    。然后()
    链接到
    openCaptcha
    调用
    验证码

    if (captchaValidated == null){
                    openRecaptcha().then(verifyCaptcha);
                }
    
    verifyCaptcha
    中,使用带有参数
    “*”
    .is()
    检查
    文档中是否存在元素

    if (grecaptcha.is("*")) {
    
    openrecomptcha()
    ,如果
    grecaptcha.render
    不返回异步结果,则使用
    .promise()
    返回jQuery promise对象;else链接到
    grecaptcha.render
    $(“#recaptchaModal”).modal('show')
    ;使用
    $.when()


    感谢@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>
    
    
    var captchaValidated=null;
    var currentRequests=[];
    var captchaPrompted=假;
    var captchaReady=假;
    var resetCaptcha=false;
    函数onloadCaptcha(){
    captchaReady=true;
    captcha=grecaptcha.render('recaptcha'{
    “sitekey”:“,
    “回调”:验证验证码,
    “过期回调”:invalidateCaptcha,
    “类型”:“音频图像”
    });
    }
    var deferredCaptcha=null;
    var promiseCaptcha=null;
    var-captcha=null;
    函数openrepatcha(){
    如果(!captchaReady){
    setTimeout(openRecaptcha,50);
    }
    如果(CAPTCHAPPROMPTED){
    返回;
    }
    captchaPrompted=真;
    var captchaTimer=setInterval(函数(){
    如果(captchaValidated!=null){
    如果(已验证){
    deferredCaptcha.resolve();
    }否则{
    deferredCaptcha.reject();
    captchaValidated=null;
    }
    }
    }, 100);
    如果(重置验证码){
    captcha.reset();
    }
    deferredCaptcha=$.Deferred();
    promiseCaptcha=延迟验证码。promiseCaptcha();
    promiseCaptcha.done(函数(){
    //验证码成功
    clearInterval(captchaTimer);
    //如果有要处理的项目,请处理队列
    如果(currentRequests.length>0){
    对于(var i=0;ireturn $.when(grecaptcha.render(/* parameters */)
           , $("#recaptchaModal").modal('show').promise())
    
    <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>