如何将reCAPTCHA设为必填项?

59

我正在使用Google reCAPTCHA,并已能够在表单中添加验证码组件。但当我提交表单时,没有进行验证来检查是否已解决验证码。

如何在提交表单时验证已解决验证码组件?换句话说,如何使我的验证码组件成为必填项?


1
抱歉gpullen,但我想在表单中将reCAPTCHA设置为必填字段。 - Baikare Sandip
2
请尝试此链接 - 如何提问 - The Blue Dog
将您的代码与相关的Google产品页面链接一起发布,这对每个人都比发布动画GIF更有用。谢谢。 - Sparky
9个回答

99

如果你想使用本机的HTML5弹出窗口,那么这里是解决方案

JavaScript:

window.addEventListener('load', () => {
  const $recaptcha = document.querySelector('#g-recaptcha-response');
  if ($recaptcha) {
    $recaptcha.setAttribute('required', 'required');
  }
})

CSS:

#g-recaptcha-response {
  display: block !important;
  position: absolute;
  margin: -78px 0 0 0 !important;
  width: 302px !important;
  height: 76px !important;
  z-index: -999999;
  opacity: 0;
}

1
我喜欢这种方法,但是出现了错误:“名称为'g-recaptcha-response'的无效表单控件无法聚焦。” - timkado
1
嗨,弗雷德 - 这非常奇怪。我复制了你的代码,但仍然出现相同的错误:名称为“g-recaptcha-response”的无效表单控件无法聚焦。 - timkado
@timkado 你使用什么操作系统上的浏览器? - Fred
4
对我很有效。@timkado遇到了相同的错误,但在添加所提供的CSS样式后问题得以解决。这是因为目标Textarea默认为"display: none;"。谢谢@Fred! - iconique
3
非常接近了,但如果验证码过期了,这个程序就无法捕捉到它。 - Robert McKee
显示剩余5条评论

21

我遇到了与你相同的问题,并通过以下方式解决:

首先声明一个变量,根据用户是否正确填写验证码存储10

var allowSubmit = false;

然后您需要一个函数,当用户正确填写reCapcha时执行:

function capcha_filled () {
    allowSubmit = true;
}

...并有一个在reCapcha会话过期时执行的函数:

function capcha_expired () {
    allowSubmit = false;
}

要告诉 reCapcha 有关您的功能(回调)的信息,请在您的 HTML 中设置这些 data- 属性:

<div class="g-recaptcha"
   data-callback="capcha_filled"
   data-expired-callback="capcha_expired"
   data-sitekey="your site key"></div>

或者,如果您使用显式加载:

  var onloadCallback = function() {
    grecaptcha.render('your_div_id', {
      'sitekey' : 'your_site_key',
      'callback': capcha_filled,
      'expired-callback': capcha_expired,
    });
  };

您还需要为表单提交添加一个回调函数:

function check_if_capcha_is_filled (e) {
    if(allowSubmit) return true;
    e.preventDefault();
    alert('Fill in the capcha!');
}

最后在表单中添加onsubmit属性:

<form action="..." onsubmit="check_if_capcha_is_filled">
注意:正如评论中提到的那样,仍然需要进行服务器验证。该代码可防止在未填写验证码的情况下意外提交表单,仅为用户方便而设

有什么办法阻止我进入JavaScript控制台并自己设置submit = true呢? - Ian MacDonald
1
@IanMacDonald 绝对没有任何问题。这只是为了用户的方便而设定的(我的回答)。这个想法是为了防止他们在没有填写验证码的情况下意外提交表单(例如,在<input>上按下回车键)。只是为了节省页面重新加载,提供更好的用户体验。 - Al.G.
哦,我现在明白了。我应该明确提到仍然需要进行服务器检查。感谢您的提醒。 - Al.G.

17

我发现这是一个快速且简单的方法。将以下内容添加到您的标头中:

<script>
window.onload = function() {
  var recaptcha = document.forms["myForm"]["g-recaptcha-response"];
  recaptcha.required = true;
  recaptcha.oninvalid = function(e) {
    // do something
    alert("Please complete the captcha");
  }
}
</script>

这仅适用于HTML5,并由以下浏览器支持(或应该支持):http://caniuse.com/#feat=form-validation

(在Chrome中的JS控制台显示此错误消息:"Invalid form control" only in Google Chrome,我无法解决这个问题。希望其他人能改进这个回答。)


这在手动测试时有效。但如果表单由机器人提交,是否仍然有效呢?:D 可能不会。 - Larstton

12

我检查了#g-recaptcha-response的存在:

function checkRecaptcha() {
    res = $('#g-recaptcha-response').val();

    if (res == "" || res == undefined || res.length == 0)
        return false;
    else
        return true;
}

//...

$('#frm-signup').submit(function(e) {

    if(!checkRecaptcha()) {
        $( "#frm-result" ).text("Please validate your reCAPTCHA.");
        return false;
    }
    //...
});

这真的应该是文档的一部分...


5

2022年的解决方案

个人经验,以上提供的解决方案都不能用于我的验证码。因此,我想分享一下我目前可用的解决方案,帮助那些遇到同样问题的人。

接受的答案没有验证技术来检测验证码是否过期,以下的解决方案解决了这个问题。

我的.js笔记应该可以详细解释这个解决方案。

JavaScript

// By default do not allow form submission.
var allow_submit = false

function captcha_filled () {
    /*
     * This is called when Google get's the recaptcha response and approves it.
     * Setting allow_submit = true will let the form POST as normal.
     * */

    allow_submit = true
}

function captcha_expired () {
    /*
     * This is called when Google determines too much time has passed and expires the approval.
     * Setting allow_submit = false will prevent the form from being submitted.
     * */

    allow_submit = false
}


function check_captcha_filled (e) {
    console.log('captcha-verified')
    /*
     * This will be called when the form is submitted.
     * If Google determines the captcha is OK, it will have
     * called captcha_filled which sets allow_submit = true
     * If the captcha has not been filled out, allow_submit
     * will still be false.
     * We check allow_submit and prevent the form from being submitted
     * if the value of allow_submit is false.
     * */

    // If captcha_filled has not been called, allow_submit will be false.
    // In this case, we want to prevent the form from being submitted.
    if (!allow_submit) {
        // This call prevents the form submission.
        // e.preventDefault()

        // This alert is temporary - you should replace it with whatever you want
        // to do if the captcha has not been filled out.
        alert('ERROR: Please verify you are human by filling out the captcha')

        return false
    }
    captcha_expired()
    return true
}

HTML

<form action="post" onsubmit="return check_captcha_filled()">
<!-- form items -->
<div class="g-recaptcha"
   data-callback="captcha_filled"
   data-expired-callback="captcha_expired"
   data-sitekey="your site key">
</div>
</form>

可能是这样,因为这个问题有点老了,随着验证码库的更改,我们可能需要相应地更新jQuery。 - Baikare Sandip
@BaikareSandip 我不确定我是否理解了。解决方案中没有jQuery。 - Kameron

2
如果您想要更友好和详细的提示信息,可以添加一个必选框。 这将确保HTML5弹出窗口显示类似于:“请勾选此框以继续”
<div class="captcha">
   <div class="g-recaptcha" data-sitekey="Your Site Key" data-callback="removeFakeCaptcha"></div>
   <input type="checkbox" class="captcha-fake-field" tabindex="-1" required>
</div>

在完成后添加代码以删除虚假验证码

window.removeFakeCaptcha = function() {
   document.querySelector('.captcha-fake-field').remove();
}

然后在CSS中隐藏复选框,并将其定位到验证码框:
.captcha {
  position: relative;
}
.captcha-fake-field {
  background: transparent;
  bottom: 0;
  border: none;
  display: block;
  height: 1px;
  left: 12px;
  width: 1px;
  position: absolute;
  z-index: -1;
}

它没有正常工作。你能帮我吗? - Anny

0

页面未找到。请尝试提供答案而非链接。 - Anny

0

一旦验证码过期,这并不是强制性的,它会继续进行按钮点击和进一步的验证。

还有其他重新验证和强制用户验证验证码的方法吗?我正在使用带复选框的Captcha V2。

enter image description here


0
我觉得这非常有帮助:
<div class="g-recaptcha myPopover" data-sitekey="Your Key" 
        data-callback="recaptchaCallback">

你需要在代码中添加一个函数,函数名为data-callback="recaptchaCallback"。
var recaptchachecked=false; 
function recaptchaCallback() {
    recaptchachecked = true;
}

还有一个函数,你可以返回值并在其他HTML标签中使用它,就像这样:

<form method="post" onsubmit="return isreCaptchaChecked()">
function isreCaptchaChecked()
{
    return recaptchachecked;
}

希望这能对你有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接