web-dev-qa-db-ja.com

jQuery検証プラグインを備えた新しいreCaptcha

よく検索しましたが、フォーム送信前に jQuery検証プラグイン の検証機能と一緒に 新しいreCaptchaを検証する の方法がわかりません。

私はこのようなことを意味します:

    $.validator.addMethod('reCaptchaMethod', function (value, element, param) {
            if (grecaptcha.getResponse() == ''){
                return false;
            } else {
                // I would like also to check server side if the recaptcha response is good
                return true
            }
        }, 'You must complete the antispam verification');


    $("#form").validate({
            rules: {
                name: {
                    required: true,
                    minlength: 2
                },
                email: {
                    required: true,
                    email: true
                },
                reCaptcha: {
                    reCaptchaMethod: true   
                }
            },
            messages: {
                name: "Please fill your name",
                email: "Please use a valid email address"
            },
            submitHandler : function () {
                        $.ajax({
                            type : "POST",
                            url : "sendmail.php",
                            data : $('#form').serialize(),
                            success : function (data) {
                                $('#message').html(data);
                            }
                        });
                    }


        });

簡単に言えば、ユーザーがフォームを送信する前に、他の検証規則とともにrecaptcha検証に合格した場合、 remote method でサーバーサイドをチェックしたいと思います。

(sendmail.phpで)提出後にrecaptchaを確認することはできますが、recaptcha検証応答と他のフィールド検証を行う方が良いでしょう。

主な理由は、すべてのフィールドを一度にチェックして、ユーザーエクスペリエンスを向上させるためです。

SubmitHandler内でチェックを移動する何かを達成することができました。

            submitHandler : function () {
                  if (grecaptcha.getResponse() == ''){
                      // if error I post a message in a div
                      $( '#reCaptchaError' ).html( '<p>Please verify youare human</p>' );

                  } else {

                        $.ajax({
                            type : "POST",
                            url : "sendmail.php",
                            data : $('#form').serialize(),
                            success : function (data) {
                                $('#message').html(data);
                            }
                        });
                    }

             }

しかし、私は2つの理由で好きではありません:1)recaptchaが有効であるかどうかではなく、埋められているかどうかをチェックするだけです。 2)ユーザーは2段階認証のように感じます。

この答えでは CAPTCHA応答の成功時に関数呼び出しを指定するために、コールバックでRecaptchaのレンダリングを完了できると彼らは言います。

私はそれを実装しようとしましたが、validate()関数のルール内でこのソリューションを使用することはできませんでした。

どんなヒントでも大歓迎です!

35
bluantinoo

私はこの質問が少し時代遅れであることを知っていますが、私は同じ問題を抱えていて、解決策を見つけました。これを行うには、reCaptcha divの横に次のような非表示フィールドを追加します。

<div class="g-recaptcha" data-sitekey="{YOUR-SITE-KEY-HERE}"></div>
<input type="hidden" class="hiddenRecaptcha required" name="hiddenRecaptcha" id="hiddenRecaptcha">

あなたのjavascriptで:

$("#form").validate({
        ignore: ".ignore",
        rules: {
            name: {
                required: true,
                minlength: 2
            },
            email: {
                required: true,
                email: true
            },
            hiddenRecaptcha: {
                required: function () {
                    if (grecaptcha.getResponse() == '') {
                        return true;
                    } else {
                        return false;
                    }
                }
            }
        },(...rest of your code)

あなたが持たなければならないことに注意ignore: ".ignore"は、jquery.validateが非表示フィールドをデフォルトで無視し、検証しないためです。

ReCapcha validateでエラーメッセージを削除する場合は、reCapcha要素にデータコールバックを追加します。

<div class="g-recaptcha" data-sitekey="{YOUR-SITE-KEY-HERE}" data-callback="recaptchaCallback"></div>

そして、あなたのjsファイルに追加します

function recaptchaCallback() {
  $('#hiddenRecaptcha').valid();
};
76
FabioG

submitHandlerでフォーム送信を防ぐこともできます

$("#loginForm").validate({
rules: {
    username: {
        required: true,
        minlength: 6
    },
    password: {
        required: true,
    },
},
submitHandler: function(form) {
    if (grecaptcha.getResponse()) {
        form.submit();
    } else {
        alert('Please confirm captcha to proceed')
    }
}
});
11
Ranjith Singhu

あなたのソリューションが面白いことがわかりました(@FabioG)。

しかし、私は自分で少し使用するためにそれを変更しました。他の人が使用するためにコードを共有したいと思っています。

私はインタラクティブなフォームで作業していました。これは、手順を完了すると検証されます。

食べ物を注文するために使われました。エルゴ、登録ボタンの検証とアクティベーションが必要なフォームであり、最新のreCaptcha(5/12/2016)を使用しています。

また、このコードは、期限切れのreCaptcha、ajaxを介したサーバー側の検証を処理します(含まれていません-必要に応じて回答を自由にコメントしてください。必要に応じて編集します)。

始めましょう。

HTMLコード:

<form id="registerForm" method="get" action="">
<fieldset class="step-1">
<h4>Step One:</h4>
<span class="clock">Register under one minute!</span>
<label for="email-register" class="label">E-mail*</label>
<input id="email-register" name="email-register" type="email" value="" autocomplete="off"/>

<label for="password-register" class="label">Password*</label>
<input id="password-register" name="password-register" type="password" value="" autocomplete="off"/>

<div class="g-recaptcha" data-sitekey="6LeS4O8SAAAAALWqAVWnlcB6TDeIjDDAqoWuoyo9" data-callback="recaptchaCallback" data-expired-callback="recaptchaExpired" style="margin-top: 3rem;"></div>
<input id="hidden-grecaptcha" name="hidden-grecaptcha" type="text" style="opacity: 0; position: absolute; top: 0; left: 0; height: 1px; width: 1px;"/>
</div>
</fieldset>
<fieldset class="step-2">
<h4>Step two:</h4>
<span class="notice">All fields with a sign are required!*</span>
<label for="first-name" class="label">First Name*</label>
<input name="first-name" id="first-name" type="text" value="" />

<label for="last-name" class="label">Last Name*</label>
<input name="last-name" id="last-name" type="text" value="" />

<label for="address" class="label">Address*</label> 
<input name="address" id="address" type="text" value=""/>

<label for="entrance" class="label">Entrance</label>    
<input name="entrance" id="entrance" type="text" value=""/>

<label for="apartment-number" class="label">Apartment #</label>
<input name="apartment-number" id="apartment-number" type="text" value="" />

<label for="inter-phone" class="label">Interphone</label>           
<input name="inter-phone" id="inter-phone" type="text" value=""/>

<label for="telephone" class="label">Mobile Number*</label>
<input name="telephone" id="telephone" type="text" value="" />

<label for="special-instructions" class="label">Special Instructions</label>    
<textarea name="special-instructions" id="special-instructions"></textarea>
<div>
</fieldset>
<button class="button-register" disabled>Register</button>
</form>

ご覧のとおり、送信用のボタン( ".button-register")は最初はdisabledです。

mandatory(*)フィールドに入力することでのみ有効にできます。

CSSは含めなかったことに注意してください。フォームは最低限必要なものであり、教育目的のためだけのものです。

@ FabioGと異なるものはほとんどありません、答えは次のとおりです:

要素を非表示にする必要も、「。ignore」を使用する必要もありません。インラインCSSで非表示にしました。

ReCaptchaが成功し、reCaptchaが期限切れになった場合、応答コールバックがあります。

したがって、フォームへの入力中にreCaptchaの有効期限が切れると、invalidになり、ボタンは再びdisabledになります。

同様に、フォームは入力フィールド(非表示の入力フィールド)を使用して情報をAJAX(PHPに送信)に渡し、サーバー側で検証します(潜在的なセキュリティリスクであるため、最後に詳しく説明しました。テキストの)。

JavaScript/jQueryに移りましょう。

JavaScript/jQuery:

function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};
function recaptchaCallback() {
    var response = grecaptcha.getResponse(),
        $button = jQuery(".button-register");
    jQuery("#hidden-grecaptcha").val(response);
    console.log(jQuery("#registerForm").valid());
    if (jQuery("#registerForm").valid()) {
        $button.attr("disabled", false);
    }
    else {
        $button.attr("disabled", "disabled");
    }
}

function recaptchaExpired() {
    var $button = jQuery(".button-register");
    jQuery("#hidden-grecaptcha").val("");
    var $button = jQuery(".button-register");
    if (jQuery("#registerForm").valid()) {
        $button.attr("disabled", false);
    }
    else {
        $button.attr("disabled", "disabled");
    }
}
function submitRegister() {
  //ajax stuff
}
(function ($, root, undefined) {
    $(function () {
        'use strict';
        jQuery("#registerForm").find("input").on("keyup", debounce(function() {
          var $button = jQuery(".button-register");
          if (jQuery("#registerForm").valid()) {
            $button.attr("disabled", false);
          }
          else {
            $button.attr("disabled", "disabled");
          }
        }, 1000));
        jQuery("#registerForm").validate({
          rules: {
            "email-register": {
              required: true,
              email: true
            },
            "password-register": {
              required: true,
              minlength: "6"
            },
            "first-name": "required",
            "last-name": "required",
            address: "required",
            telephone: "required",
            "hidden-grecaptcha": {
              required: true,
              minlength: "255"
            }
          },
          messages: {
            "email-register": "Enter valid e-mail address",
            "password-register": {
              required: "Enter valid password",
              minlength: "Password must be bigger then 6 chars!"
            },
            "first-name": "Required!",
            "last-name": "Required!",
            address: "Required!",
            telephone: "Required!"
          },
          submitHandler: submitRegister
        });
    }); 
})(jQuery, this);

ここでわかるように、いくつかの関数があります:recaptchaCallback()およびrecaptchaExpired()

recaptchaCallback()データ属性を介して埋め込まれるdata-callbackgrecaptcha.getResponse()reCaptchaが検証されているかどうかを確認します。検証されている場合は、トークンを非表示の入力フィールドに入力し、jQuery( "#registerForm).validate();を介して再検証を要求します。

ただし、reCaptchaが期限切れになった場合、「data-expired-callback」で割り当てられた関数を使用して、入力フィールドからトークンを削除し、フィールドが空であるため失敗する再検証を再度要求します。これは、関数recaptchaExpired()で実現されます。

コードの後半で、jQuery keyup関数を追加して、再検証を確認し、ユーザーが入力フィールドに必要な情報を渡したかどうかを確認できます。情報とフィールドが正常に検証されると、keyup関数はRegisterボタンを有効にします。

また、keyupでデバウンススクリプト(tnx、David Walsh)を使用しました。したがって、ブラウザの遅延は発生しません。なぜなら、多くの入力があるからです。

ただし、ユーザーがreCaptchaを回避することを決めた場合、入力フィールドに常に「255」文字の文字列を入力できることに注意してください。しかし、さらに一歩踏み込んで、reCaptchaを確認するためにAJAX検証サーバー側を作成しました。

このコードは、以前の回答に対するわずかな改善だと考えています。質問がある場合やAJAX/PHPコードが必要な場合は、お気軽にコメントしてください。できるときに供給します。

Codepenもここにあります: jQuery.validationを使用したreCaptcha

ReCatpchaのデータ属性と関数に関するすべての情報は、APIで見つけることができます: reCaptcha API

それが誰かを助けたことを願っています!

よろしく、

2
steviss

私は今日これに苦労し、最終的には行きました:

<form onsubmit="return $(this).valid() && grecaptcha.getResponse() != ''">

これは最も簡単な方法のように感じます。誰かがそのようにjsをインライン化することに文句を言うはずですが、私は大丈夫です。

0
pguardiario