You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google reCAPTCHA v3集成遇阻求助:添加验证后表单失效

Google reCAPTCHA v3 实现问题排查与修复

我是新手开发者,正在做网站开发,死活搞不定Google reCAPTCHA v3的实现。看了一堆教程视频还是找不到问题——给按钮加g-recaptcha类后表单就没法正常工作,删掉这个类表单就恢复正常了。下面是我跟着教程写的代码:

原代码展示

JavaScript代码

<script src="https://www.google.com/recaptcha/api.js"></script>

<script>
   function onSubmit(token) {
     document.getElementById("contact-form").submit();
	}
 </script>

HTML表单代码

<div class="rainbow-contact-area rainbow-section-gapBottom" data-sal="slide-up" data-sal-duration="400" data-sal-delay="150">
    <div class="container">
        <div class="row mt--40 row--15">
            <div class="col-lg-7">
                <form class="contact-form-1 rainbow-dynamic-form" id="contact-form" method="POST" action="mail.php">
                    <div class="form-group">
                        <input type="text" name="contact-name" id="contact-name" placeholder="Your Name">
                    </div>
                    <div class="form-group">
                        <input type="text" name="contact-phone" id="contact-phone" placeholder="Phone Number">
                    </div>
                    <div class="form-group">
                        <input type="email" id="contact-email" name="contact-email" placeholder="Your Email">
                    </div>

                    <div class="form-group">
                        <input type="text" id="subject" name="subject" placeholder="Your Subject">
                    </div>

                    <div class="form-group">
                        <textarea name="contact-message" id="contact-message" placeholder="Your Message"></textarea>
                    </div>
                    
                    <div class="form-group text-center">
                        <button name="submit" type="submit" id="submit" class="btn-default btn-large rainbow-btn g-recaptcha" data-sitekey="site_key" data-callback='onSubmit' data-action='submit'>Submit Now</button>
                    </div>
                </form>
            </div>

PHP代码

<?php

if ($_SERVER['REQUEST_METHOD'] == 'POST') {

    $recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
    $recaptcha_secret = 'sercet_key';
    $recaptcha_response = $_POST['g-recaptcha-response'];

    $recaptcha = file_get_contents($recaptcha_url . '?secret=' . $recaptcha_secret . '&response=' . $recaptcha_response);
    $recaptcha = json_decode($recaptcha, true);

    $name = trim($_POST['contact-name']);
    $phone = trim($_POST['contact-phone']);
    $email = trim($_POST['contact-email']);
    $message = trim($_POST['contact-message']);
    if ($name == "") {
        $msg['err'] = "
 Name can not be empty!";
        $msg['field'] = "contact-name";
        $msg['code'] = FALSE;
    } else if ($phone == "") {
        $msg['err'] = "
 Phone number can not be empty!";
        $msg['field'] = "contact-phone";
        $msg['code'] = FALSE;
    } else if (!preg_match("/^[0-9 \-\+]{4,17}$/i", trim($phone))) {
        $msg['err'] = "
 Please put a valid phone number!";
        $msg['field'] = "contact-phone";
        $msg['code'] = FALSE;
    } else if ($email == "") {
        $msg['err'] = "
 Email can not be empty!";
        $msg['field'] = "contact-email";
        $msg['code'] = FALSE;
    } else if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
        $msg['err'] = "
 Please put a valid email address!";
        $msg['field'] = "contact-email";
        $msg['code'] = FALSE;
    } else if ($message == "") {
        $msg['err'] = "
 Message can not be empty!";
        $msg['field'] = "contact-message";
        $msg['code'] = FALSE;
    } else {
        $to = 'myemail2@mymail.com';
        $subject = 'Website Form Submission';
        $_message = '<html><head></head><body>';
        $_message .= '<p>Name: ' . $name . '</p>';
        $_message .= '<p>Message: ' . $phone . '</p>';
        $_message .= '<p>Email: ' . $email . '</p>';
        $_message .= '<p>Message: ' . $message . '</p>';
        $_message .= '</body></html>';

        $headers = 'MIME-Version: 1.0' . "
";
        $headers .= 'Content-type: text/html; charset=iso-8859-1' . "
";
        $headers .= 'From: <myemail@mymail.com' . "
";
        $headers .= 'cc: myemail2@mymail.com' . "
";
        mail($to, $subject, $_message, $headers, '-f myemail@mymail.com');

        $msg['success'] = "
 Email has been sent successfully.";
        $msg['code'] = TRUE;
    }
}
echo json_encode($msg);?>

问题根源与修复方案

核心问题

你用了reCAPTCHA v2的调用方式(g-recaptcha类+点击回调)来实现v3,但v3是隐形验证,不需要用户手动触发验证,而是在后台自动完成打分。另外PHP代码存在逻辑顺序错误、拼写错误和内容错误。

修改后的完整代码

1. JavaScript代码(适配v3逻辑)

<script src="https://www.google.com/recaptcha/api.js?render=你的站点密钥"></script>
<script>
document.getElementById('contact-form').addEventListener('submit', function(e) {
  e.preventDefault(); // 阻止默认提交行为
  // 调用reCAPTCHA v3获取验证token
  grecaptcha.execute('你的站点密钥', {action: 'submit'}).then(function(token) {
    // 创建隐藏字段存储token,提交给后端验证
    let tokenInput = document.createElement('input');
    tokenInput.type = 'hidden';
    tokenInput.name = 'g-recaptcha-response';
    tokenInput.value = token;
    document.getElementById('contact-form').appendChild(tokenInput);
    // 提交表单
    document.getElementById('contact-form').submit();
  });
});
</script>

2. HTML按钮(移除v2相关属性)

<button name="submit" type="submit" id="submit" class="btn-default btn-large rainbow-btn">Submit Now</button>

3. PHP代码(修正逻辑与错误)

<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $msg = [];
    // 第一步:先验证reCAPTCHA
    $recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
    $recaptcha_secret = '你的密钥'; // 注意拼写是secret,原代码写的sercet是错误的
    $recaptcha_response = $_POST['g-recaptcha-response'] ?? '';

    // 用urlencode避免参数拼接错误
    $recaptcha = file_get_contents($recaptcha_url . '?secret=' . urlencode($recaptcha_secret) . '&response=' . urlencode($recaptcha_response));
    $recaptcha = json_decode($recaptcha, true);

    // 验证是否通过,score阈值可根据需求调整(0-1,越高越像真人)
    if (!$recaptcha['success'] || $recaptcha['score'] < 0.5) {
        $msg['err'] = "机器人验证失败,请重试!";
        $msg['code'] = FALSE;
        echo json_encode($msg);
        exit; // 验证失败直接终止流程
    }

    // 第二步:校验表单字段
    $name = trim($_POST['contact-name'] ?? '');
    $phone = trim($_POST['contact-phone'] ?? '');
    $email = trim($_POST['contact-email'] ?? '');
    $message = trim($_POST['contact-message'] ?? '');

    if ($name == "") {
        $msg['err'] = "姓名不能为空!";
        $msg['field'] = "contact-name";
        $msg['code'] = FALSE;
    } else if ($phone == "") {
        $msg['err'] = "手机号不能为空!";
        $msg['field'] = "contact-phone";
        $msg['code'] = FALSE;
    } else if (!preg_match("/^[0-9 \-\+]{4,17}$/i", $phone)) {
        $msg['err'] = "请输入有效的手机号!";
        $msg['field'] = "contact-phone";
        $msg['code'] = FALSE;
    } else if ($email == "") {
        $msg['err'] = "邮箱不能为空!";
        $msg['field'] = "contact-email";
        $msg['code'] = FALSE;
    } else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $msg['err'] = "请输入有效的邮箱地址!";
        $msg['field'] = "contact-email";
        $msg['code'] = FALSE;
    } else if ($message == "") {
        $msg['err'] = "留言内容不能为空!";
        $msg['field'] = "contact-message";
        $msg['code'] = FALSE;
    } else {
        $to = 'myemail2@mymail.com';
        $subject = '网站表单提交';
        // 用htmlspecialchars防止XSS注入
        $_message = '<html><head></head><body>';
        $_message .= '<p>姓名: ' . htmlspecialchars($name) . '</p>';
        $_message .= '<p>手机号: ' . htmlspecialchars($phone) . '</p>'; // 原代码把phone写成Message,已修正
        $_message .= '<p>邮箱: ' . htmlspecialchars($email) . '</p>';
        $_message .= '<p>留言: ' . htmlspecialchars($message) . '</p>';
        $_message .= '</body></html>';

        $headers = 'MIME-Version: 1.0' . "\r\n";
        $headers .= 'Content-type: text/html; charset=utf-8' . "\r\n"; // 改成utf-8避免中文乱码
        $headers .= 'From: <myemail@mymail.com>' . "\r\n"; // 原代码From标签未闭合,已修正
        $headers .= 'cc: myemail2@mymail.com' . "\r\n";
        
        // 发送邮件并判断结果
        if(mail($to, $subject, $_message, $headers, '-f myemail@mymail.com')){
            $msg['success'] = "邮件发送成功!";
            $msg['code'] = TRUE;
        } else {
            $msg['err'] = "邮件发送失败,请稍后重试!";
            $msg['code'] = FALSE;
        }
    }
    echo json_encode($msg);
}
?>

额外注意事项

  • 替换代码中的你的站点密钥和你的密钥为Google reCAPTCHA控制台获取的真实密钥,注意区分站点密钥(site key)和密钥(secret key)
  • reCAPTCHA v3的score阈值(0.5)可根据业务调整,比如垃圾请求多的话可以提高到0.7
  • 生产环境建议用cURL替代file_get_contents,避免因allow_url_fopen关闭导致请求失败

内容的提问来源于stack exchange,提问作者DARKLiING

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 16:15:09