web-dev-qa-db-ja.com

HTML5検証に合格した場合にのみreCaptchaを実行する方法は?

通常、HTML5フォーム検証は before submitイベントを実行します。

これとともに

<form id="myForm">
    <input  type="text" name="foo" required />

    <button type="submit"> Submit </button>

</form>

<script>
    $("#myForm").on('submit',function(){
        console.log("I'm entering the submit event handler");
    });
</script>

入力フィールドが空の場合、送信イベントハンドラーは実行されません。 HTML5検証(この場合はrequired属性)が合格した場合にのみトリガーされます。

キャプチャが実行されると期待します after HTML5検証も。後でフィールドが見つからないことを警告する場合、ユーザーがキャプチャをコンパイルするのをイライラさせる必要があるのはなぜですか? 最初私はユーザーに正しい方法ですべてを強制する必要があります、 then ボットではなく人間であることを確認してください、私見。

どうやら、reCaptchaはアタッチしたフォーム上で何かを行い、HTML5検証機能を削除します。

たとえば、最新の Invisible reCaptcha を使用します。

<form id="myForm">
    <input  type="text" name="foo" required />

    <button type="submit"
           class="g-recaptcha" 
    data-sitekey="your_site_key" 
   data-callback='myCallback'> Submit </button>

</form>

<script>
    function myCallback(token){
        $("#myForm").submit();
    }

    $("#myForm").on('submit',function(){
        console.log("I'm entering the submit event handler");
    });
</script>

フォームは、ユーザーにその義務について通知せずに、空のフィールドで送信されます。

なぜそれがこのように機能するかについての手がかりはありますか? reCaptchaに制御を行う前にHTML5フォーム検証を実行するように指示する方法はありますか?

14
Andrea Ligios

ReCAPTCHA属性をボタンに直接アタッチする代わりに、divに追加し、フォーム送信時にgrecaptcha.execute();を使用する必要があります。

_<script src="https://www.google.com/recaptcha/api.js" async defer></script>

<form id="myForm">
    Name: (required) <input id="field" name="field" required>
    <div id='recaptcha' class="g-recaptcha"
         data-sitekey="your_site_key"
         data-callback="onCompleted"
         data-size="invisible"></div>
    <button id='submit'>submit</button>
</form>
<script>
    $('#myForm').submit(function(event) {
        console.log('validation completed.');

        event.preventDefault(); //prevent form submit before captcha is completed
        grecaptcha.execute();
    });

    onCompleted = function() {
        console.log('captcha completed.');
    }
</script>
_

ReCAPTCHA属性をボタンに追加した場合、Googleはボタンにクリックリスナーを追加し、ボタンがクリックされたときにreCAPTCHAを実行します。追加された送信リスナーはありません。 HTML5検証は、送信ボタンをクリックすることでのみトリガーされ、送信イベントのbeforeを実行します。そのため、reCAPTCHAが送信イベントの後にafterを実行することを確認する必要があります。 reCAPTCHAがサブスクライブしているクリックイベントは、内部HTML5検証がトリガーされる前に処理されているようです。 submit()を使用してフォームを送信しても、検証はトリガーされません。それはまさにその関数が定義された方法です。コールバックで関数を呼び出すため、検証はトリガーされません。ただし、コールバックでsubmit()関数を呼び出さなかった場合でも、reCAPTCHAはデフォルトの動作からイベントを停止し、検証を完全に停止するようです。

reCAPTCHA完了後にフォームを送信

ReCAPTCHAの完了後に送信されたフォームを取得する場合は、grecaptcha.getResponse()の結果を確認できます。

_<script src="https://www.google.com/recaptcha/api.js" async defer></script>

<form id="myForm">
    Name: (required) <input id="field" name="field" required>
    <div id='recaptcha' class="g-recaptcha"
         data-sitekey="your_site_key"
         data-callback="onCompleted"
         data-size="invisible"></div>
    <input type="submit" value="submit" />
</form>
<script>
    $('#myForm').submit(function(event) {
        console.log('form submitted.');

        if (!grecaptcha.getResponse()) {
            console.log('captcha not yet completed.');

            event.preventDefault(); //prevent form submit
            grecaptcha.execute();
        } else {
            console.log('form really submitted.');
        }
    });

    onCompleted = function() {
        console.log('captcha completed.');
        $('#myForm').submit();
        alert('wait to check for "captcha completed" in the console.');
    }
</script>
_
30
maechler

maechlerの答えは優れていますが、jQueryを使用したくない場合は、iifeでイベントリスナーを追加できます

(function() {
    document.getElementById("my-form").addEventListener("submit", function(event) {
        console.log('form submitted.');
        if (!grecaptcha.getResponse()) {
            console.log('captcha not yet completed.');

            event.preventDefault(); //prevent form submit
            grecaptcha.execute();
        } else {
            console.log('form really submitted.');
        }
      });
  })();

それがお役に立てば幸いです。

1
bird