web-dev-qa-db-fra.com

Google INVISIBLE Numéro reCaptcha + jQuery validate ()

J'ai implémenté le nouveau le reCaptcha INVISIBLE de Google sur plusieurs sites, mais il est en conflit avec jQuery validate (), de sorte que la validation js n'est plus exécutée lors de la soumission du bouton/formulaire, et reCaptcha entre instantanément . Si l'utilisateur oublie de renseigner un champ de formulaire obligatoire, il devra attendre la réponse du serveur et y revenir ultérieurement.

jQuery .validate () prend en charge le rappel, mais étant donné qu'il est codé en dur dans une classe interne d'un système de gestion de contenu, existe-t-il un moyen de le modifier en quelque sorte en dehors (par exemple à partir d'un thème frontal, du chargement de document, lorsque code de validation est déjà rendu)?

Une autre idée serait de reporter le rappel de captcha d’une manière ou d’une autre, afin que cette étape de validation puisse avoir une chance de s’exécuter.

Merci!

jQuery Valider le formulaire: (codé en dur dans le noyau, impossible de modifier, sauf si j'édite un fichier principal ou que j'étends la fonction classe/clone - pas optimal)

<script type="text/javascript">
$(document).ready(function(){
    $("form[name=comment_form]").validate({
        rules: {
            body: {
                required: true,
                minlength: 1
            },
            authorEmail: {
                required: true,
                email: true
            }
        },
        wrapper: "li",
        errorLabelContainer: "#comment_error_list",
        invalidHandler: function(form, validator) {
            $('html,body').animate({ scrollTop: $('#comment_error_list').offset().top }, { duration: 250, easing: 'swing'});
        },
        submitHandler: function(form){
            $('button[type=submit], input[type=submit]').attr('disabled', 'disabled');
            form.submit();
        }
    });
});
</script>

reCaptcha rendu explicite:

<script type='text/javascript'>
    var renderInvisibleReCaptcha = function() {
    for (var i = 0; i < document.forms.length; ++i) {
        var form = document.forms[i];
        var holder = form.querySelector('.invisible-recaptcha');
        if (null === holder) continue;
        (function(frm){
            var holderId = grecaptcha.render(holder, {
            'sitekey': 'my-key-here',
            'badge': 'inline',
            'size': 'invisible',
            'callback': function (recaptchaToken) {HTMLFormElement.prototype.submit.call(frm);},
            'expired-callback': function(){grecaptcha.reset(holderId);}
            });
            frm.onsubmit = function (evt){evt.preventDefault();grecaptcha.execute(holderId);};
        })(form);
    }
};
</script>
6
dev101

J'avais le même problème et je validais le formulaire avant d'exécuter invisible reCaptcha à l'aide de ce link fourni par Terry.

Voici les étapes:

Ajoutez cette div avant le bouton d'envoi dans votre formulaire

 <div id='recaptcha' class="g-recaptcha"
      data-sitekey="your_site_key"
      data-callback="onSubmit"
      data-size="invisible"></div>

Mettez à jour votre clé aussi. Après la fermeture du formulaire, ajoutez cette méthode

<script>onload();</script>

Avant votre formulaire, ajoutez ce code

<script>
function validate(event) {
 event.preventDefault();
 if (!document.getElementById('field').value) {
   alert("You must add text to the required field");
 } else {
   grecaptcha.execute();
 }
}

function onload() {
 var element = document.getElementById('submit');
 element.onclick = validate;
}
</script>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>

Effectuez toutes les validations dans la méthode validate et si toutes les validations aboutissent, exécutez captcha. 

6
Abdul Jamil

J'ai eu le même problème, j'ai finalement trouvé le bon moyen d'intégrer jquery validate avec invisible reCaptcha. C'est un mélange de certaines des solutions proposées ici. 

Tout d’abord, la partie HTML:

<div class="g-recaptcha" data-sitekey="<your key here>"
    data-size="invisible" 
    data-callback="formSubmit">
</div>

Ensuite, vous devez implémenter le rappel reCaptcha de cette façon:

function formSubmit(response) {
    // submit the form which now includes a g-recaptcha-response input
     $("#orderform").submit();
    return true;
}

Et enfin, la partie la plus délicate est dans le submitHandler de jquery validate:

   submitHandler: function (form) {
        if (grecaptcha.getResponse()) {
                // 2) finally sending form data
                form.submit();
        }else{
                // 1) Before sending we must validate captcha
            grecaptcha.reset();
            grecaptcha.execute();
        }           
    }

La séquence est la suivante:

  1. Lorsque l'utilisateur clique sur le bouton de soumission, le paramètre submitHandler de jquery est appelé, car Invisible recaptcha n'est pas encore exécuté, nous appelons grecaptcha.execute () . La recaptcha de Google prend quelques secondes pour valider, et quand entièrement validé, il appelle callSubmit Callback (tant que ce rappel n'est pas appelé, nous ne pouvons pas envoyer de données de formulaire au serveur!).
  2. Dans callSubmit callback, nous appelons $ ('# orderform'). Submit pour forcer à entrer de nouveau SubmitHandler. 
  3. Dans submitHandler à nouveau, cette fois comme Grecaptcha.getResponse n’est pas nul, nous pouvons poster les données du formulaire sur le serveur Il inclura le champ caché recaptcha, qui doit ensuite être validé du côté serveur. .

J'espère que cela t'aides.

5
Joan Fabre Gras

Ce qui a fonctionné pour moi a été d’utiliser jquery pour sélectionner le formulaire (j’avais utilisé getElementByID), puis de "renvoyer true". Donc au lieu de cela:

        <script src="https://www.google.com/recaptcha/api.js" async defer></script>
        <script>
            function onSubmit(token) {
                document.getElementById("frm").submit();
            }
        </script>
        <button class="g-recaptcha btn btn-block btn-primary" data-sitekey="<YOUR_KEY>" data-callback='onSubmit'>Submit</button>

utilisez ceci:

        <script src="https://www.google.com/recaptcha/api.js" async defer></script>
        <script>
            function onSubmit(token) {
                $("#frm").submit();
                return true;
            }
        </script>
        <button class="g-recaptcha btn btn-block btn-primary" data-sitekey="<YOUR_KEY>" data-callback='onSubmit'>Submit</button>
0
dstark

Techniquement, tout ce que nous "voulons" vraiment faire est de lier le défi à un bouton par programmation. Par exemple:

Ajoutez cette méthode, que nous voulons uniquement exécuter, la méthode invisible grecaptcha au lieu de la validation "réelle"

 jQuery.validator.addMethod("iv_recapcha_valid", function(value, element) {
        return grecaptcha.execute();
    }, 'No message needed, grecaptcha excecuted'); 

Ajoutez ensuite cette règle à vos règles existantes

rules: { gRecaptchaResponse: { iv_recapcha_valid: true } }

ajouter un champ caché

<input type="hidden" name="gRecaptchaResponse" value="" >

Maintenant, "techniquement", le bouton d'envoi est lié à l'action de clic de l'utilisateur 

https://developers.google.com/recaptcha/docs/invisible

0

J'ai eu le même problème sur le modèle classique Asp.Net Core MVC . Il a été décoré en interne par la validation Unobstrusive . Après l'insertion de Invisible Recaptcha, la validation a été rompue . En lisant cet article, j'ai réussi à le faire fonctionner, en utilisant la validation intégrée, sans qu'il soit nécessaire de spécifier la validation pour chaque champ (inféré par Model Class dans le projet MVC)

Page HTML:

 <input type="hidden" name="gRecaptchaResponse" id="gRecaptchaResponse" value="" /> 

            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <div id='recaptcha' class="g-recaptcha"
                         data-sitekey="@_configuration["InvisibleRecaptcha:SiteKey"]"
                         data-callback="SubmitRegistration"
                         data-size="invisible"></div>
                    <button type="submit" id="SubmitButton" class="btn btn-primary"> Invia</button>
                </div>
            </div>

Code Javascript:

 <script>

        function onload() {
            var element = document.getElementById('SubmitButton');
            element.onclick = validate;
        }
        onload();

        function validate(event) {
            event.preventDefault();

            $("#Form").validate();
            var isFormValid = $("#Form").valid();
            if (isFormValid) {
                grecaptcha.execute();
            }
        }

        function SubmitRegistration(data) {
            if ($("#gRecaptchaResponse").val() == '') {
                $("#gRecaptchaResponse").val(data);
            }
            document.getElementById("Form").submit();
        }  

    </script>

J'espère que ce morceau de code peut aider quelqu'un

0
Giulio Fronterotta