【问题标题】:Parsley + recaptcha v3 promiseParsley + recaptcha v3 承诺
【发布时间】:2021-12-15 09:53:38
【问题描述】:

我无法让以下代码工作:

$(function() {
    function verifyRecaptcha() {
        return new Promise((resolve, reject) => {
            grecaptcha.execute('RECAPTCHA_SITE_KEY', {action: 'submit'}).then(function(token) {
                postJson('frontend/verify_recaptcha/'+token, null, function(d) {
                    if (d.pass) {
                        resolve('Verified');
                    } else {
                        reject('Not verified');
                    }
                });
            });
        });
    };

    var parsleyForm = $('#enquiry-form').parsley().on('form:submit', function(formInstance) {
        var validationResult = false;

        verifyRecaptcha().then(function() {
            console.log('VERIFIED');
            validationResult = true
        }).catch(function() {
            console.log('NOT VERIFIED');
            validationResult = false;
        });

        console.log('Resultat: '+validationResult);

        return validationResult;
    });
});

我已经用 await/async 尝试了很多,但它总是提交表单。

我认为我不能是唯一需要使用 recaptcha v3 实施 Parsley 的人吗?有任何想法吗? :)

【问题讨论】:

    标签: javascript jquery parsley.js


    【解决方案1】:

    我用这个:

    // Returns the current form that the recaptcha widget is appended on
    const form = getRecaptchaForm();
    // I use a different input from the standard 'g-recaptcha-response', but you can use the one appended by recaptcha
    const input = form.elements.namedItem('g-recaptcha-response');
    // Keep track of validation time
    let lastToken, lastTokenDate;
    
    // Use a polyfilled version of form.requestSubmit (https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/requestSubmit)
    // See Safari bug: https://webkit.org/b/197958
    const requestSubmit = function () {
        let submitter = form.querySelector('input[type=\"submit\"],button[type=\"submit\"]');
        if (!submitter) {
            submitter = document.createElement('input');
            submitter.type = 'submit';
            submitter.hidden = true;
            form.appendChild(submitter);
            submitter.click();
            form.removeChild(submitter);
        }
        else {
            submitter.click();
        }
    };
    
    // This submits the form as if the user clicked the submit button
    const submitRecaptcha = function (token, error) {
        lastToken = input.value = token;
        lastTokenDate = Date.now();
        if (error) {
            console.warn('Recaptcha error', error);
        }
        requestSubmit();
    };
    
    // The submit handler must be bound on the form itself (not as a delegate from a parent)
    form.addEventListener('submit', function handleRecaptcha(e) {
        // Validation token is still valid
        if ((input.value && (input.value === lastToken) && (lastTokenDate > (Date.now() - (2 * 60 * 1000)))) || (e.defaultPrevented === true) || (e.target !== form)) {
            return;
        }
    
        try {
            // Stop form submission and also prevent other handlers from triggering until the recaptcha promise is resolved
            e.preventDefault();
            e.stopPropagation();
    
            // Validate the recaptcha
            grecaptcha.ready(function () {
                grecaptcha.execute('RECAPTCHA_SITE_KEY', { action: 'submit' })
                .then(function (token) {
                    // Do something else with the token before submitting the form
                    postJson('frontend/verify_recaptcha/' + token, null, function(d) {
                        if (d.pass) {
                            // Now we trigger the other submit handlers (will also trigger our `handleRecaptcha` handler, but will return because the lastTokenDate is still valid)
                            submitRecaptcha(token);
                        }
                        else {
                            // Ensure the other submit handlers get triggered
                            submitRecaptcha('error', d);
                        }
                    });
                })
                .catch(function (e) {
                    // Ensure the other submit handlers get triggered
                    submitRecaptcha('error', e);
                });
            });
        }
        catch (e) {
            // Ensure the other submit handlers get triggered
            submitRecaptcha('error', e);
        }
    }, /* Must use capture phase to prevent other custom events from triggering ahead of this */ true);
    

    该实现不支持 parsley.js,理论上您可以使用任何验证库,但我在绑定了 parsley.js 的表单上对其进行了测试。 recaptcha 复选框装饰由 google 处理,因此无需创建自定义 parsley.js 异步验证器自行处理。

    【讨论】:

      猜你喜欢
      • 2016-11-25
      • 2017-08-25
      • 2019-02-22
      • 2022-01-19
      • 2020-04-16
      • 1970-01-01
      • 2019-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多