web-dev-qa-db-ja.com

Google INVISIBLE reCaptcha + jQuery validate()の問題

私はいくつかのサイトで新しい GoogleのINVISIBLE reCaptcha を正常に実装しましたが、ボタン/フォームの送信時にjs検証が実行されなくなり、即座にreCaptchaが実行されるため、jQueryのvalidate()と競合します。キックイン。ユーザーが必要なフォームフィールドに入力するのを忘れた場合、サーバーの応答を待機し、次回はそのフィールドに戻る必要があります。

jQuery .validate()はコールバックをサポートしますが、CMSの内部クラス内にハードコードされているため、外部で(たとえば、フロントエンドテーマから、ドキュメントの読み込み時に)変更できる方法があります。検証コードは既にレンダリングされています)?

または、別のアイデアは、何らかの方法でキャプチャのコールバックを延期して、検証ステップを実行する機会を得るというものです。

ありがとう!

jQuery検証フォーム:(コアファイルを編集するか、クラス/クローン関数を拡張しない限り、コアにハードコードされ、変更できません-最適ではありません)

<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の明示的なレンダリング:

<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>
8
dev101

私は同じ問題を抱えていましたが、jquery検証を非表示のreCaptchaと統合する正しい方法をようやく見つけました。これは、ここで提案されているソリューションのいくつかの組み合わせです。

まず、HTMLの部分:

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

次に、その方法でreCaptchaコールバックを実装する必要があります。

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

そして最後に、トリッキーな部分はjquery validateのsubmitHandlerにあります。

   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();
        }           
    }

シーケンスは次のとおりです。

  1. ユーザーが送信ボタンを押すと、jqueryのsubmitHandlerが呼び出されます。非表示のrecaptchaはまだ実行されていないため、grecaptcha.execute()を呼び出します。 googleのreaptchaが検証されるまで数秒かかり、それが完全に検証されると、formSubmitコールバックが呼び出されます(このコールバックが呼び出されていない間は、フォームデータをサーバーに送信できません!)。
  2. FormSubmitコールバックでは、$( '#orderform')。submitを呼び出して、submitHandlerに再び入るよう強制します。
  3. もう一度submitHandler内で、今回はgrecaptcha.getResponseがnullではないので、フォームデータをサーバーに投稿できます。これには、recaptcha非表示フィールドが含まれます。このフィールドはサーバー側で検証する必要があります。

お役に立てれば。

8
JoanF

私は同様の問題を抱えていて、Terryから提供された link を使用して invisible reCaptcha を実行する前にフォームを検証していました。

手順は次のとおりです。

フォームの送信ボタンの前にこのdivを追加します

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

キーも更新します。フォームを閉じた後、このメソッドを追加します

<script>onload();</script>

フォームの前にこのコードを追加します

<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>

Validateメソッドですべての検証を実行し、すべての検証が成功した場合はcaptchaを実行します。

6
Abdul Jamil

技術的には、「本当に」やりたいのは、チャレンジをボタンにプログラムでバインドすることだけです。例えば:

このメソッドを追加します。これは、「実際の」検証の代わりに非表示のgrecaptchaを実行するだけです。

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

次に、このルールを既存のルールに追加します

rules: { gRecaptchaResponse: { iv_recapcha_valid: true } }

非表示フィールドを追加する

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

これで、「技術的に」送信ボタンがユーザーのクリックアクションにバインドされます

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

私にとってうまくいったのは、jqueryを使用してフォームを選択し(私はgetElementByIDを使用していた)、「trueを返す」ことでした。したがって、これの代わりに:

        <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>

これを使って:

        <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

従来のAsp.Net Core MVCテンプレートで同じ問題が発生しました。それは、控えめな検証によって内部的に装飾されました。非表示の再キャプチャを挿入した後、検証が失敗しました。この記事を読んで、統合された検証を使用して、すべてのフィールドの検証を指定する必要なしに、それを機能させることができました(MVCプロジェクトへのモデルクラスによって推定)

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>

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>

このコードが誰かを助けることを願っています

0