2015-04-10 17 views
15

Tôi đã tìm kiếm rất nhiều nhưng tôi không thể tìm ra cách để validate the new reCaptcha, trước khi gửi biểu mẫu, cùng với chức năng xác thực của jQuery validation Plugin.New reCaptcha với jQuery Validation Plugin

Ý tôi là một cái gì đó như thế này:

$.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); 
          } 
         }); 
        } 


     }); 

Trong một vài từ, tôi muốn kiểm tra serverside, với remote method, nếu người dùng đã thông qua việc xác nhận reCAPTCHA trước khi nộp mẫu đơn, cùng với các quy tắc khác xác thực.

Tôi có thể kiểm tra recaptcha SAU KHI gửi (trên sendmail.php), nhưng sẽ đẹp hơn nếu có xác nhận xác thực lại xác thực cùng với các xác thực trường khác.

Lý do chính là để có trải nghiệm người dùng tốt hơn, có tất cả các trường được chọn cùng một lúc.

tôi đã quản lý để đạt được một cái gì đó di chuyển séc bên trong 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); 
          } 
         }); 
        } 

      } 

Nhưng tôi không thích cho 2 lý do: 1) Tôi chỉ cần kiểm tra nếu reCAPTCHA đã được lấp đầy, không nếu nó hợp lệ. 2) Người dùng cảm thấy giống như xác minh 2 bước.

In this answer họ nói rằng nó có thể được thực hiện hiển thị Recaptcha trên gọi lại, để chỉ định một cuộc gọi hàm trên phản hồi CAPTCHA thành công.

Tôi đã cố thực hiện điều đó, nhưng tôi đã không thể sử dụng giải pháp này trong quy tắc của hàm validate().

Bất kỳ gợi ý nào đều được hoan nghênh!

+0

là nó an toàn để xác minh phản ứng reCAPTCHA từ phía khách hàng? Bạn bao gồm secret_key như thế nào? lợi thế của việc xác minh phía máy chủ là gì? – user557657

Trả lời

44

Tôi biết câu hỏi này là một chút ngày nhưng tôi đã có cùng một vấn đề và chỉ tìm thấy giải pháp. Bạn có thể làm điều này bằng cách thêm một lĩnh vực tiềm ẩn bên cạnh div reCaptcha, như:

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

sau đó trong javascript của bạn:

$("#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) 

thông báo rằng bạn phải có ignore: ".ignore" trong mã của bạn vì jquery.validate bỏ qua các trường ẩn theo mặc định, không xác nhận chúng.

Nếu bạn muốn loại bỏ các thông báo lỗi trên reCapcha xác nhận thêm một dữ liệu gọi lại tới phần tử reCapcha

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

Và sau đó trong file js của bạn thêm

function recaptchaCallback() { 
    $('#hiddenRecaptcha').valid(); 
}; 
+0

Tuyệt vời! Cảm ơn bạn đã làm rõ cách hoạt động này – AndyD273

+0

tuyệt vời! rất đơn giản và hoạt động hoàn hảo, cảm ơn bạn. – Offboard

+0

kịch bản hay .. nhưng làm cách nào để xóa thông báo lỗi về thành công của captcha ?? cảm ơn trước – Gomzy

0

tôi phải vật lộn với một ngày hôm nay và kết thúc đi với:

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

Mà chỉ cảm thấy giống như cách đơn giản nhất để làm điều đó. Ai đó nhất định phàn nàn về việc đặt js vào nội tuyến như thế nhưng tôi ổn với nó.

+0

vấn đề là tôi muốn tích hợp xác thực xác thực bằng jQuery .Validate() fuction, vì vậy tôi có thể trình bày cho người dùng một danh sách lỗi duy nhất trong các trường điền. Xin lỗi nhưng tôi không hiểu làm thế nào để đạt được điều đó bằng cách sử dụng giải pháp của bạn? – bluantinoo

1

tôi đã tìm thấy bạn giải pháp thú vị (@FabioG).

Nhưng, tôi đã sửa đổi nó để sử dụng một chút một mình và tôi sẵn sàng chia sẻ mã để người khác sử dụng.

Tôi đang làm việc trên biểu mẫu tương tác, được xác thực khi bạn hoàn thành các bước.

Nó được sử dụng để đặt món ăn. Ergo, mẫu yêu cầu xác minh và kích hoạt của nút đăng ký và nó đang sử dụng reCaptcha mới nhất cho đến nay (5/12/2016).

Ngoài ra, mã này xử lý reCaptcha hết hạn, xác minh phía máy chủ qua ajax (bột không được bao gồm - nếu ai đó cần cảm thấy tự do để nhận xét câu trả lời của tôi và tôi sẽ chỉnh sửa nó cho phù hợp).

Cho phép bắt đầu.

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

Như bạn có thể thấy, các nút trình (".button đăng ký") là bước đầu người tàn tật.

Bạn chỉ có thể bật tính năng này bằng cách điền vào các trường bắt buộc (*).

Xin lưu ý rằng tôi không bao gồm bất kỳ CSS nào. Biểu mẫu ở mức tối thiểu và chỉ dành cho mục đích giáo dục.

vài điều mà khác với @FabioG, câu trả lời là:

Không cần để ẩn phần tử hoặc sử dụng ".ignore". Tôi đã ẩn nó với CSS nội tuyến.

Có một số gọi lại trả lời cho reCaptcha thành công và đã hết hạn reCaptcha.

Vì vậy, nếu reCaptcha của bạn hết hạn trong khi điền vào mẫu nó sẽ làm cho nó không hợp lệ và nút sẽ tàn tật một lần nữa.

Đồng thời, biểu mẫu sử dụng trường nhập (trường nhập ẩn) để chuyển thông tin lên AJAX (PHP sau này) và xác minh bên máy chủ (Đó là một nguy cơ bảo mật tiềm ẩn, cuối của văn bản).

Cho phép chuyển sang 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); 

Như bạn có thể thấy ở đây, có một vài chức năng: recaptchaCallback()recaptchaExpired().

recaptchaCallback() được embeded qua các dữ liệu thuộc tính dữ liệu callback, sử dụng grecaptcha.getResponse() để xem nếu reCaptcha được xác nhận, nếu có thì nó đi vào thẻ đến trường nhập ẩn và yêu cầu tái xác nhận thông qua jQuery ("# registerForm) .validate();.

Tuy nhiên , nếu reCaptcha hết hạn trong khi đó, nó sẽ sử dụng hàm được gán trong "data-expired-callback", để loại bỏ mã thông báo khỏi trường nhập và yêu cầu xác nhận lại lần nữa sẽ thất bại vì trường này trống. đạt được với các chức năng recaptchaExpired().

Sau đó trong mã bạn có thể thấy rằng chúng tôi đã thêm một jQuery KeyUp chức năng, để kiểm tra lại xác nhận và xem liệu người dùng đã chuyển thông tin được yêu cầu cho các trường nhập liệu chưa. Nếu thông tin và trường xác nhận thành công chức năng keyup sẽ bật nút Đăng ký.

Ngoài ra, tôi đã sử dụng tập lệnh gỡ lỗi (tnx, David Walsh) trên keyup. Vì vậy, nó không gây lag trình duyệt. Kể từ đó, sẽ có rất nhiều cách gõ.

Tuy nhiên, hãy nhớ nếu người dùng quyết định phá vỡ reCaptcha, anh ấy luôn có thể nhập chuỗi dài ký tự "255" vào trường nhập. Nhưng, tôi đã tiến thêm một bước nữa và thực hiện một máy chủ xác minh AJAX để xác nhận reCaptcha. Bột, tôi đã không bao gồm nó trong câu trả lời.

Nó nghĩ rằng mã này là một cải thiện biên trên câu trả lời trước đó. Nếu bạn có bất kỳ câu hỏi nào hoặc cần mã AJAX/PHP, hãy bình luận. Tôi sẽ cung cấp nó khi tôi có thể.

Heres codepen cũng như: reCaptcha with jQuery.validation

Bạn có thể tìm thấy tất cả các thông tin liên quan đến việc reCatpcha dữ liệu thuộc tính và chức năng trong api của họ vào đây: reCaptcha API

Hy vọng nó sẽ giúp một ai đó!

Kính trọng,

1

Bạn cũng có thể ngăn chặn các hình thức nộp trong 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') 
    } 
} 
}); 
Các vấn đề liên quan