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

使用Ajax+PHP实现Google reCAPTCHA v2时第二个验证码无响应问题

问题描述

我正在尝试用 Ajax 和 PHP 实现 Google reCAPTCHA v2,但完成验证后无法获取响应。我配置了两个使用不同密钥的 reCAPTCHA,其中第一个能正常工作。之前多次修改代码,曾出现验证码验证成功但页面跳转到 contact.php、未按预期返回结果的情况,现在陷入困境。相关代码如下:

前端HTML

<div class="g-recaptcha" data-sitekey="你的前端站点密钥"></div>

前端Ajax代码

$.ajax({
    type: "POST",
    url: "contact.php",
    data: {
        name: name,
        email: email,
        subject: subject,
        message: message,
        captcha: grecaptcha.getResponse()
    }
}).done(function (response) {
    var parsedResponse = JSON.parse(response);
    if (!parsedResponse.success) {
        $('#response').text(parsedResponse.message);
        $('#contact_form_2')[0].reset();
    } else {
        $('#response').text("Wiadomość została wysłana.");
    }
}).fail(function (jqXHR, textStatus, errorThrown) {
    $('#response').text('Wystąpił błąd podczas wysyłania wiadomości.');
});

后端PHP代码

$recaptcha_secret = '你的后端密钥';
$rresponse=$_POST["captcha"];

$recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
$recaptcha_data = array(
    'secret' => $recaptcha_secret,
    'response' => $rresponse
);

$recaptcha_options = array(
    'http' => array(
    'method' => 'POST',
    'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
    'content' => http_build_query($recaptcha_data)
    )
);

$recaptcha_context = stream_context_create($recaptcha_options);
$recaptcha_result = file_get_contents($recaptcha_url, false, $recaptcha_context);
$recaptcha_json = json_decode($recaptcha_result);

if (!$recaptcha_json->success) {
    $response = array('success' => false, 'message' => 'Potwierdzenie reCAPTCHA nie powiodło się.');
    echo json_encode($response);
    return;
}

解决步骤

1. 阻止表单默认提交行为

之前页面跳转到 contact.php 是因为表单触发了默认提交事件,和Ajax请求冲突。需要在表单提交事件中添加阻止默认行为的代码:

$('#contact_form_2').on('submit', function(event) {
    // 阻止表单默认跳转
    event.preventDefault();
    
    // 确保正确获取表单输入值
    var name = $('#name').val();
    var email = $('#email').val();
    var subject = $('#subject').val();
    var message = $('#message').val();
    var captchaResponse = grecaptcha.getResponse();

    // 先检查是否完成验证码验证
    if (!captchaResponse) {
        $('#response').text('请完成reCAPTCHA验证');
        return;
    }

    $.ajax({
        type: "POST",
        url: "contact.php",
        data: {
            name: name,
            email: email,
            subject: subject,
            message: message,
            captcha: captchaResponse
        }
    }).done(function (response) {
        var parsedResponse = JSON.parse(response);
        if (!parsedResponse.success) {
            $('#response').text(parsedResponse.message);
            $('#contact_form_2')[0].reset();
            // 重置验证码,方便用户重新验证
            grecaptcha.reset();
        } else {
            $('#response').text("消息已发送");
            $('#contact_form_2')[0].reset();
            grecaptcha.reset();
        }
    }).fail(function (jqXHR, textStatus, errorThrown) {
        $('#response').text('发送消息时出错,请稍后重试');
        grecaptcha.reset();
    });
});

2. 完善后端PHP的错误处理与验证逻辑

关键修改点:

  • 检查空的验证码响应
  • 确保密钥与前端配对
  • 处理file_get_contents请求失败的情况
  • 解析reCAPTCHA的具体错误码
<?php
// 先验证是否收到验证码响应
if (empty($_POST["captcha"])) {
    echo json_encode(['success' => false, 'message' => '请完成reCAPTCHA验证']);
    exit;
}

$recaptcha_secret = '你的后端密钥'; // 必须与前端sitekey配对
$rresponse = $_POST["captcha"];

$recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
$recaptcha_data = [
    'secret' => $recaptcha_secret,
    'response' => $rresponse,
    'remoteip' => $_SERVER['REMOTE_ADDR'] // 可选:传递用户IP提升验证准确性
];

$recaptcha_options = [
    'http' => [
        'method' => 'POST',
        'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
        'content' => http_build_query($recaptcha_data),
        'timeout' => 10 // 设置超时,避免长期等待
    ]
];

$recaptcha_context = stream_context_create($recaptcha_options);
$recaptcha_result = file_get_contents($recaptcha_url, false, $recaptcha_context);

// 检查请求是否成功
if ($recaptcha_result === false) {
    echo json_encode(['success' => false, 'message' => '无法连接到reCAPTCHA服务器']);
    exit;
}

$recaptcha_json = json_decode($recaptcha_result);

// 检查JSON解析是否正常
if (json_last_error() !== JSON_ERROR_NONE) {
    echo json_encode(['success' => false, 'message' => '解析验证响应失败']);
    exit;
}

if (!$recaptcha_json->success) {
    // 获取具体错误原因,方便调试
    $errorMsg = 'reCAPTCHA验证失败';
    if (!empty($recaptcha_json->error_codes)) {
        $errorMsg .= ',错误代码:' . implode(', ', $recaptcha_json->error_codes);
    }
    echo json_encode(['success' => false, 'message' => $errorMsg]);
    exit;
}

// 验证成功后的业务逻辑(比如发送邮件)
// ...

echo json_encode(['success' => true, 'message' => '验证通过']);
?>

3. 调试技巧

  • 浏览器控制台:打开F12的Network标签,查看Ajax请求的状态码、响应内容,确认是否有请求失败或返回异常。
  • 后端日志:在PHP中添加error_log()记录关键变量(如$rresponse、$recaptcha_result),排查数据传递是否正常。
  • 密钥配对检查:确保前端data-sitekey和后端$recaptcha_secret是同一组reCAPTCHA的密钥,不能混用不同项目的密钥。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 01:08:26