如何在js中检查用户是否已经勾选了Google reCAPTCHA复选框?

97
我已经在head结束之前添加了以下内容
<script src='https://www.google.com/recaptcha/api.js'></script>

我已在表单结束前添加了这个

<div class="g-recaptcha" data-sitekey="== xxxxxx =="></div>

我能看到与 https://developers.google.com/recaptcha/ 相似的 reCAPTCHA。

然而,当用户在未勾选复选框的情况下提交数据时,数据仍会被提交。是否需要添加其他代码来检查用户是否按下了复选框?最好使用 JavaScript 实现。


2
你有阅读过这个页面吗:https://developers.google.com/recaptcha/docs/verify - Daniel A. White
唉..似乎无法弄清楚如何让这个工作。 - Hello Universe
你应该在后端服务器上发起请求。让浏览器独自处理这个请求不太安全。 - Daniel A. White
没问题。如何从前端请求,可能使用jQuery? - Hello Universe
7个回答

205

谷歌提供了回调选项,当复选框被选中时可用。

将以下内容添加到您的表单元素中:

data-callback="XXX"

例子:

<div class="g-recaptcha" data-callback="recaptchaCallback" data-sitekey="== xxxxxx =="></div>
给您的提交按钮添加一个禁用属性。
示例:
<button id="submitBtn" disabled>Submit</button>

接下来创建一个回调函数并编写您需要的任何代码。

例如:

function recaptchaCallback() {
    $('#submitBtn').removeAttr('disabled');
};

1
@mohanenb:这只是为了防止发送,而不是像通常一样检查服务器端。 - halfbit
2
如何解决超时问题?如果有人检查了reCaptcha,然后在几分钟内没有提交表单,则reCaptcha将过期,但用户仍能够提交表单..! - Akshay Kapoor
3
data-expired-callback 是一个回调函数,用于在 reCAPTCHA 数据过期时执行相应的操作。 - xinthose
5
提醒您将函数recaptchaCallback()放在document.ready之外,以便验证码控件可以访问它。否则,您将收到一个console.log错误,如“ReCAPTCHA couldn't find user-provided function:”。请注意不要改变原文意思。 - ForTheWin
1
这个解决方案仅在验证码被解决时调用一个函数,但没有提供一个函数来检查验证码是否已被解决。 - João Pimentel Ferreira
显示剩余6条评论

82

您还可以调用grecaptcha对象进行检查。当未选中时,grecaptcha.getResponse();为空,当选中后,则包含验证代码。

当未选中时,grecaptcha.getResponse().length === 0

function isCaptchaChecked() {
  return grecaptcha && grecaptcha.getResponse().length !== 0;
}

if (isCaptchaChecked()) {
  // ...
}

但是,如何获取grecaptcha.getResponse()? - Nitin Dhomse
只要加载谷歌的reCAPTCHA,它就会被加载。这是软件包的一部分。 - Olafur Tryggvason
我尝试了但是不起作用,控制台调试显示>> "Uncaught ReferenceError: grecaptcha未定义"。 - silvachathura
脚本应该首先加载reCAPTCHA,尝试使用异步或setTimeout来完成。 - Denys Klymenko
2
var isCaptchaChecked = (grecaptcha && grecaptcha.getResponse().length !== 0); - jaybro
显示剩余2条评论

14

要检查 Google reCAPTCHA 是否被选中,您可以使用以下代码:

<script>

if(grecaptcha && grecaptcha.getResponse().length > 0)
{
     //the recaptcha is checked
     // Do what you want here
     alert('Well, recaptcha is checked !');
}
else
{
    //The recaptcha is not cheched
    //You can display an error message here
    alert('Oops, you have to check the recaptcha !');
}

</script>

4
为了检查是否已经勾选了 Google reCAPTCHA v2,您可以使用以下代码:
var checkCaptch = false;
     var verifyCallback = function(response) {
        if (response == "") {
             checkCaptch = false;
         }
         else {
             checkCaptch = true;
         }
     };
     $(document).ready(function() {
         $("#btnSubmit").click(function() {
             if (checkCaptch && grecaptcha.getResponse()!="") {
                  //Write your success code here
             }
         });
     })

4
让浏览器为您完成工作!(基于slinky2000的答案)
注意:这仅用于防止发送“意外”未选中的reCaptcha。因为机器人不关心...,所以您仍然需要在服务器端验证reCaptcha。
在下方添加一个带有required=true属性的不可见输入标签。
<input id='recaptcha_check_empty' required tabindex='-1',
style='width:50px; height:0; opacity:0; pointer-events:none; 
position:absolute; 
bottom:0;'>

将两个宽度用position=relative;div包围起来,以便将在recaptcha底部上方指向bottom:0;

现在浏览器会友好地提示您填写此字段-指向recaptcha。

现在我们需要回调函数:

<div class="g-recaptcha" data-callback="recaptchaCallback" ...

并且

function recaptchaCallback() { 
    $('#recaptcha_check_empty').val(1);
}

0
如果你像我一样手动编写表单,并且 required 不起作用,那么可以尝试以下步骤:
首先导入 ReCAPTCHA。
import  ReCAPTCHA  from 'react-google-recaptcha'

将其应用于您的组件中

<ReCAPTCHA style={{margin: '5px', transform: 'scale(0.8)'}} ref={recaptchaRef} sitekey={recaptchaKey} onChange={updateRecaptcha}/>

你可以使用 useRef 或者直接使用你导入的 ReCAPTCHA,我使用了 useRef

const recaptchaRef = useRef<any>()

现在,我该如何检查recaptchaRef是否被选中?

if (recaptchaRef.current.props.grecaptcha.getResponse().length !== 0) {
    //your condition
}

基本上,你是在说'如果Recaptcha为真,则执行此操作'

这是完整的表单代码,可帮助您(我正在使用TypeScript)

const Formid = // yout formid
const FormSpark = `https://submit-form.com/${Formid}`

type FormState =  {
    name: string,
    mail: string,
    message: string
}
const initialState = {
    name: '',
    mail: '',
    message: '',
}

const [wrongmail, setWrongmail] = useState(false)
const [wrongname, setWronname] = useState(false)
const [wrongtext, setWrongtext] = useState(false)
const [alert, setAlert] = useState(false)
const recaptchaRef = useRef<any>()
const recaptchaKey = //your recaptcha public key    const [recaptchaToken, setRecaptchaToken] = useState<string>()
const [formstate, setFormState] = useState<FormState>(initialState)
const submit = async(event: FormEvent) =>{
    event.preventDefault()
    await postSubmission()
}
const updateRecaptcha = (token: string | null)=>{
    setRecaptchaToken(token as string)
}
const {name, mail, message} = formstate
const postSubmission = async() => {
    const payload = {
        ...formstate,
        "g-recaptcha-response": recaptchaToken
    }
    try {
        if (name && mail && message) {
            if (mail.includes('@') && mail.includes('.') && mail.length > 5) {
                if (name.includes(' ') && name.length> 5) {
                    if (message.length > 20) {
                        if (recaptchaRef.current) {
                            if (recaptchaRef.current.props.grecaptcha.getResponse().length !== 0) {
                                console.log('hola')
                                setAlert(true)
                                const result = await axios.post(FormSpark, payload)
                                setFormState(initialState)
                                recaptchaRef.current.reset()
                                if (result) {
                                    setTimeout(() => {
                                        setAlert(false)
                                    },2000)
                                }
                            }
                        }
                    }
                }
            }
            if (!name && !(name.length> 5) && !(name.includes(' '))) {
                setWronname(true)
                setTimeout(() => {
                    setWronname(false)
                },3000)
            }
            if (!mail && !mail.includes('@') && !mail.includes('.') && !(mail.length > 5)) {
                setWrongmail(true)
                setTimeout(()=>{
                    setWrongmail(false)
                },3000)
            }
            if (!message && !(message.length > 20)) {
                setWrongtext(true)
                setTimeout(() => {
                    setWrongtext(false)
                },3000)
            }
        }
    } catch(error){
        console.log(error);
    }
}

const updateForm = (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
    const {id, value} = event.target
    const formKey = id as keyof FormState
    const updatedFormState = {...formstate}
    updatedFormState[formKey] = value
    setFormState(updatedFormState)
}

0
<div class="contact-inner contact-message">
  <label for="message-text" class="col-form-label">CAPTCHA</label>
  <div class="g-recaptcha" data-sitekey="<?php echo 6LfSJmocAAAAAFFMpMKB1CtYNJYDyDswO7GpxRXS ;?>">
  </div>
</div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src='https://www.google.com/recaptcha/api.js'></script>
<!DOCTYPE html>
<html>
  <head>
    <title>CAPTCHA</title>
  </head>
  <body>
      <div class="contact-inner contact-message">
        <label for="message-text" class="col-form-label">CAPTCHA</label>
        <div class="g-recaptcha" data-sitekey="<?php echo GOOGLE_KEY ;?>"></div>
      </div>
  </body>
</html>

3
目前你的回答写得不太清楚。请编辑并添加额外的细节,以帮助他人理解这个答案如何回答所提出的问题。您可以在帮助中心中找到更多有关如何编写良好答案的信息。 - Community
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community

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