Google reCAPTCHA提示站点未验证令牌返回invalid-input-response错误如何解决?
错误原因
- 表单字段参数匹配错误:表单中reCAPTCHA响应值的隐藏字段
name属性为g-recaptcha_response(下划线分隔),但后端PHP中用$_POST['g-recaptcha-response'](中划线分隔)取值,PHP接收POST参数是按name属性匹配,因此拿到的是空值,触发无效响应错误。 - 请求URL拼接语法错误:后端发起校验请求的代码中,
&response=参数后多写了多余的.符号,且字符串拼接语法错误,导致传给Google校验接口的响应值本身是错误格式。 - Token获取时机错误:reCAPTCHA生成的Token有效期仅为2分钟,当前代码在页面加载时就生成Token,若用户打开页面后超过2分钟再提交表单,Token已过期,会校验失败。
- 请求方式不符合接口要求:Google reCAPTCHA的siteverify校验接口推荐使用POST请求,当前用GET方式拼接参数可能存在编码异常、参数长度超限等问题。
- (可选)密钥配置错误:若排除以上代码问题仍报错,需检查站点密钥、服务密钥是否为reCAPTCHA v3类型且配对,站点域名是否已添加到reCAPTCHA后台的允许域名列表中。
修复方案
1. 修正表单字段匹配
修改后端接收参数的代码,和表单name属性保持一致:
// 原代码:$recaptcha_response = $_POST['g-recaptcha-response']; // 改为: $recaptcha_response = $_POST['g-recaptcha_response'];
2. 修正校验请求的拼接语法、改为POST请求
替换原有file_get_contents的GET请求逻辑,改用标准POST请求:
$recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify'; $recaptcha_secret = '替换为你自己的服务密钥'; $recaptcha_response = $_POST['g-recaptcha_response']; // 构造POST参数 $postData = [ 'secret' => $recaptcha_secret, 'response' => $recaptcha_response, 'remoteip' => $_SERVER['REMOTE_ADDR'] ]; $context = stream_context_create([ 'http' => [ 'method' => 'POST', 'header' => 'Content-Type: application/x-www-form-urlencoded', 'content' => http_build_query($postData) ] ]); $recaptcha = file_get_contents($recaptcha_url, false, $context); $recaptcha = json_decode($recaptcha);
3. 调整Token生成时机,改为表单提交时生成
替换原有JS代码,监听表单提交事件,提交前再生成Token:
window.addEventListener("load", function(){ const form = document.getElementById('modal-container-screw'); form.addEventListener('submit', function(e) { // 阻止默认提交,等Token生成后再提交 e.preventDefault(); grecaptcha.ready(function() { grecaptcha.execute('替换为你自己的站点密钥', {action:'validate_captcha'}) .then(function(token) { document.getElementById('g-recaptcha-response').value = token; // Token赋值后再提交表单 form.submit(); }); }); }); });
4. (可选)密钥配置校验
登录Google reCAPTCHA后台确认:
- 所用密钥为reCAPTCHA v3类型,站点密钥和服务密钥配对正确
- 当前访问的站点域名已添加到允许列表,本地测试需添加
localhost到允许列表
内容的提问来源于stack exchange,提问作者Sergey_nd
相关产品推荐
相关产品推荐

