使用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
相关产品推荐
相关产品推荐

