在reCAPTCHA之前进行HTML5表单验证

时间:2017-01-15 20:28:42

标签: html5 recaptcha html5-validation

我集成了新的隐藏reCAPTCHA(v2)框架,该框架默认使用提交按钮的click事件验证用户。但是在内置HTML5表单验证之前触发此事件。我正在寻找一种方法来按预期的顺序进行:首先是表单验证,然后是reCAPTCHA。

7 个答案:

答案 0 :(得分:31)

由于采用了新的v2 grecaptcha方法,您必须以编程方式执行此操作:grecaptcha.execute()以便recaptcha不会替换按钮的默认点击事件,这会阻止默认的HTML5表单验证。

事件路径是:

  1. 提交按钮点击事件:浏览器内置表单验证
  2. 表单提交活动:致电grecaptcha.execute()
  3. reCAPTCHA回调:提交表单
  4. $('#form-contact').submit(function (event) {
        event.preventDefault();
        grecaptcha.reset();
        grecaptcha.execute();
      });
    
    function formSubmit(response) {
      // submit the form which now includes a g-recaptcha-response input
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://www.google.com/recaptcha/api.js"></script>
    <form action="?">
      <div class="g-recaptcha" 
           data-sitekey="your-key"
           data-size="invisible"
           data-callback="formSubmit">
      </div>
      <button type="submit">Submit</button>
    </form>

答案 1 :(得分:4)

以下是我获取HTML5验证+ Invisible recaptcha的解决方案:

<强> HTML:

% Downsampling of the audio file to ensure compatibility with EEG-Data
% Extracts musical features (envelope) of a song.
% Input: Audio File
% Author: A. B.
% Date: 06.02.2017

clc;
clear;

% get infos (e.g. sample rate)
info = audioinfo('03 Black Smoke.wav');
[input,Fs] = audioread('03 Black Smoke.wav');
plot(input)

% plot in frequency domain
n = length(input)-1;
f = 0:Fs/n:Fs;
wavefft = abs(fft(input)); 
figure (2);
plot(f,wavefft); 

% downsampling audio file
[P,Q] = rat(500/Fs);
abs(P/Q*Fs-500);
xnew = resample(input,P,Q);
figure (3);
plot(xnew);

% plot in frequency domain downsamplet 
n = length(xnew)-1;
f2 = 0:Fs/n:Fs;
wavefft2 = abs(fft(xnew)); 
figure (4);
plot(f2,wavefft2); 

% save downsampled audio file
audiowrite('xnew.wav',xnew,500);
info_ds = audioinfo('xnew.wav');

[input_ds,Fs_ds] = audioread('xnew.wav');
figure (5);
plot(input_ds);

% cut the file to 3 min length and save
samples = [1,180*500];
[input_cut, Fs_cut] = audioread('xnew.wav', samples);

audiowrite('input_cut.wav',input_cut,500);
info_cut = audioinfo('input_cut.wav');

% % play audio with different sample rates (control)
% P_orig = audioplayer(input,44100);
% P_new = audioplayer(input_ds,500);
% play(P_orig);
% stop(P_orig);
% play(P_new);
% stop(P_new);

% extract musical features - envelope
[wa,fs]=wavread('input_cut.wav');

<强> JS:

<form id="my-form">
    <!-- Your form fields ... -->
    <div class="g-recaptcha"
        data-sitekey="..."
        data-callback="submitMyForm"
        data-size="invisible">
    </div>
    <button type="submit">Submit</button>
</form>

答案 2 :(得分:4)

你在这里得到了一个有效的解决方案。使用隐形Recaptcha。

jQuery(document).ready(function() {
    var commentform = jQuery("#commentform");
    commentform.on("click", "#submit-comment", function(e) {
      if(commentform[0].checkValidity()) {
        e.preventDefault();
        grecaptcha.execute();
      }
    });
});

function submitCommentForm(data) {
    document.getElementById("commentform").submit();
}
<form action="blaba.php" method="post" id="commentform" class="comment-form">
  <div class="form-submit">
    <div data-callback="submitCommentForm" data-sitekey="yourkey" class="g-recaptcha" data-size="invisible">
    <button id="submit-comment">Leave a comment</button>
  </div>
</form>

答案 3 :(得分:2)

我想要同样的行为,但是使用新的recaptcha,看不见的那个。在查看了一些代码并测试了一些内容后,我深入研究了这个问题。主要区别在于此还使用默认浏览器验证

var contact_form;
$(function() {
    contact_form = $('#contact-form');
    contact_form.submit(function (event) {
        if ( ! contact_form.data('passed')) {
            event.preventDefault();
            grecaptcha.execute();
        }
    });
});
function sendContactForm(token) {
    contact_form.data('passed', true);
    contact_form.submit();
}

它基本上将jquery表单对象存储在全局var中,包括使用sendContactForm作为回调,但是当由recaptcha调用时,它设置一个名为passed的数据var,它允许形式不被阻止。这与recaptcha通常会做的完全相同,但是具有这种条件。

更新:重新查看我的代码,提醒我可能需要一种方法来恢复grecaptcha执行后传递给false的数据。如果您要实现这一点,请考虑一下。

答案 4 :(得分:1)

这是我的解决方法。

  • 使用reCaptcha v3(不可见)docs
  • 使用本地HTML5表单验证
  • 使用纯JS
  • 使用标准的POST处理(可以修改为AJAX)

根据需要添加任意多个表单,只需在两个位置更改“ UNIQUE_FORM_ID”,然后更新该表单的POST_URL。 确保在“ RECAPTCHA_SITE_KEY”的位置中使用自己的密钥。

<form id="UNIQUE_FORM_ID" method="post" action="POST_URL">
    <!-- ** Notice ** this hidden input field that will later send our g-recaptcha token back to our server -->
    <input type="hidden" name="g-recaptcha-response" value="">
    <!-- Add other hidden nonce fields -->

    <!-- Required field -->
    <input name="fullname" type="text" placeholder="Full Name" required>

    <!-- Submit button -->
    <!-- ** Notice ** the 'form' attribute; using SAME value as it's parent's form id, above. -->
    <!-- ** Notice ** the 'onclick' attribute; be sure to pass event -->
    <button type="submit" form="UNIQUE_FORM_ID" onclick="formSubmitBtn(event)">Send</button>
</form>

<!-- Only add scripts once -->
<!-- ** Notice ** to manually call grecaptcha, our site key must be included when loading api.js using the 'render' query param -->
<script src="https://www.google.com/recaptcha/api.js?render=RECAPTCHA_SITE_KEY"></script>
<script>
    /**
     * Handles form submissions for Google recaptcha v3.
     * Allows for HTML5 form validation to complete before processing.
     */
    function formSubmitBtn($event) {
        /**
         * Checks the validity of the form.
         * Return if invalid; HTML5 validation errors should display.
         */
        if (!$event.target.form.checkValidity()) {
            return;
        }
        /**
         * Form is client-side valid; taking over the remainder of processing.
         */
        $event.preventDefault();
        grecaptcha.ready(function() {
            grecaptcha.execute("RECAPTCHA_SITE_KEY", { action: 'submit' }).then(function(token) {
                /**
                 * Adds the token g-recaptcha-response token to our hidden form element.
                 * ** Notice ** we our referencing the specific form's input element by name here (do not use IDs).
                 */
                $event.target.form.elements['g-recaptcha-response'].value = token;
                /**
                 * Use the form API directly to submit the form.
                 */
                $event.target.form.submit();
            });
        });
    }
</script>

答案 5 :(得分:0)

 let siteKey = "...";
 $("form").submit(function (eventObj) {
        var myForm = this;
        eventObj.preventDefault();
        grecaptcha.execute( siteKey, {
            action: "submit"
        })
            .then(function (token) {
                $('<input />').attr('type', 'hidden')
                    .attr('name', "g_recaptcha_response")
                    .attr('value', token)
                    .appendTo(myForm);
                myForm.submit();
            });
    });

这将执行recapcha,等待响应,并在浏览器尝试提交然后实际提交时将隐藏属性g_recaptcha_response添加到任何表单。您需要全局变量siteKey

答案 6 :(得分:0)

我遇到了这个问题,因为默认方法似乎覆盖了html5表单验证。我还希望所有代码都是通用的,而不是硬编码任何函数/元素名称。最后,我使用v3 api提出了以下代码-

HTML

<form method="post" action="?" class="ui-recaptcha" name="my_form_name">
   ...
   <input type="submit" value="Submit">
</form>
<script src="//www.google.com/recaptcha/api.js?render={key}" async defer></script>

JavaScript(我使用的是jQuery,但是很容易适应普通js)

$('.ui-recaptcha').submit(e => {

    var form = e.target;

    if( $(form).data('recaptcha-done') )
        return;

    e.preventDefault();
    grecaptcha.execute('{key}', {'action': $(form).attr('name')}).then(token => {

        $(form).append($('<input>').attr({'type': 'hidden', 'name': 'g-recaptcha-response', 'value': token}));
        $(form).data('recaptcha-done', true);
        $(form).submit();
    });
});

我发现像上面的某些示例中那样仅调用submit会给我造成一个循环,当recaptcha处理程序在submit事件上运行时,这很有意义。

这将为任何ui-recaptcha表单运行recaptcha,将表单name属性作为操作在reCaptcha控制台中可见,然后将令牌插入表单。运行后,它将在表单上设置一个data属性,因此递归调用提交不会尝试再次运行recaptcha。