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

表单无视Google reCAPTCHA验证仍提交,疑与AJAX验证脚本相关

问题根源及解决方案

你的核心问题出在前端JS没有在表单提交前强制校验reCAPTCHA是否完成验证,同时后端PHP的逻辑顺序也有优化空间,导致即使验证码未通过,请求依然会发送到后端(虽然后端会返回错误,但这会浪费资源,且机器人可以直接绕过前端提交请求)。

1. 前端JS的问题分析与修复

原来的代码依赖validator()插件的默认验证,但该插件并没有包含reCAPTCHA的校验规则,所以即使用户没完成验证码验证,!e.isDefaultPrevented()依然会返回true,导致AJAX请求被触发。

修改后的JS代码如下:

$(function ValidateEmailForm() {
    window.verifyRecaptchaCallback = function (response) {
        $('input[data-recaptcha]').val(response).trigger('change')
    };
    window.expiredRecaptchaCallback = function () {
        $('input[data-recaptcha]').val("").trigger('change')
    };

    $('#contact-form').validator();

    $('#contact-form').on('submit', function (e) {
        // 先阻止默认提交行为
        e.preventDefault();
        
        // 1. 检查reCAPTCHA是否已完成验证
        const recaptchaResponse = grecaptcha.getResponse();
        if (!recaptchaResponse) {
            $('#contact-form').find('.messages').html(
                '<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>请完成reCAPTCHA验证后再提交</div>'
            );
            return;
        }

        // 2. 检查表单其他字段的验证结果
        if (!$(this).validator('validate').has('.has-error').length) {
            const url = "contact.php";
            $.ajax({
                type: "POST",
                url: url,
                data: $(this).serialize(),
                success: function (data) {
                    const messageAlert = 'alert-' + data.type;
                    const messageText = data.message;
                    const alertBox = `<div class="alert ${messageAlert} alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>${messageText}</div>`;
                    
                    if (messageAlert && messageText) {
                        $('#contact-form').find('.messages').html(alertBox);
                        $('#contact-form')[0].reset();
                        grecaptcha.reset();
                    }
                }
            });
        }
    });
});

关键修改点:

  • 先调用e.preventDefault()阻止默认提交,避免意外提交
  • 手动检查grecaptcha.getResponse()的返回值,为空则直接提示错误并终止流程
  • 确保表单其他字段通过validator验证后,才发送AJAX请求

2. 后端PHP的逻辑优化

原来的PHP代码是先初始化邮件并尝试发送,再检查reCAPTCHA的验证结果,这会导致即使验证码验证失败,邮件发送的无用操作已经执行。我们需要先验证reCAPTCHA,通过后再处理邮件逻辑:

修改后的PHP代码片段:

try {
    // 第一步:先验证reCAPTCHA
    $secretKey = "YOUR_ACTUAL_SECRET_KEY"; // 替换成你的真实密钥
    $responseKey = $_POST['g-recaptcha-response'];
    $userIP = $_SERVER['REMOTE_ADDR'];
    
    $url = "https://www.google.com/recaptcha/api/siteverify?secret=$secretKey&response=$responseKey&remoteip=$userIP";
    $response = file_get_contents($url);
    $response = json_decode($response);
    
    if (!$response->success) {
        throw new \Exception('reCAPTCHA验证失败,请重试');
    }

    // 第二步:验证通过后,再处理邮件发送
    $mail = new PHPMailer(true);
    $mail->SMTPDebug = 0;
    $mail->isSMTP();
    $mail->Host = 'YOUR_SMTP_HOST';
    $mail->SMTPAuth = true;
    $mail->Username = 'YOUR_SMTP_USER';
    $mail->Password = 'YOUR_SMTP_PASS';
    $mail->SMTPSecure = 'ssl';
    $mail->Port = 465;
    $mail->WordWrap = 50;
    $mail->Priority = 1;
    $mail->CharSet = 'utf-8';
    $mail->setFrom('YOUR_FROM_EMAIL', 'YOUR_FROM_NAME');
    $mail->addAddress('YOUR_TARGET_EMAIL');
    $mail->addReplyTo($email);
    $mail->isHTML(true);
    
    $mail->Subject = 'NY BESKED - EXAMPLE';
    $mail->Body = 'YOUR_HTML_BODY_CONTENT';
    $mail->AltBody = 'YOUR_PLAIN_TEXT_BODY_CONTENT';
    
    $mail->send();
    
    $responseArray = array('type' => 'success', 'message' => $okMessage);
} catch (\Exception $e) {
    $responseArray = array('type' => 'danger', 'message' => $e->getMessage());
}

关键优化点:

  • 将reCAPTCHA验证放在最前面,失败则直接抛出异常,避免后续无用的邮件初始化操作
  • 确保只有验证码验证通过后,才会执行邮件发送逻辑

重要提醒

即使前端做了校验,后端的reCAPTCHA验证依然是必须的——机器人可以直接绕过前端,构造POST请求提交表单,后端的验证是最后一道防线,绝对不能省略。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:24:45