Google reCAPTCHA V3验证仅返回size和timeout字段无score问题排查
问题根因
你代码里拿到的google_res不是reCAPTCHA校验接口返回的业务数据,是fetch API返回的原生HTTP Response实例。你没有调用响应解析方法读取响应体内容,自然拿不到success、score这类接口返回字段,你看到的size: 0、timeout: 0是原生Response对象自带的属性,和reCAPTCHA返回结果完全无关。
另外现有代码还有两个逻辑问题:
- 校验不通过时返回201状态码不符合HTTP语义,会误导前端判定请求成功
- 把密钥和token直接拼在URL上传参,不如放到POST请求体规范
修复方案
- 拿到fetch返回的Response对象后,调用
.json()方法解析响应体,拿到实际的校验结果对象 - 调整传参方式,将校验参数以
application/x-www-form-urlencoded格式放到POST请求体中传递 - 修正状态码:校验失败返回400状态码,服务内部异常返回500状态码
修复后的完整后端校验代码:
const createItem = async (req, res) => { try { const tempItem = req.body.item; const itempieces = req.body.itempieces; const captcha = req.body["g-recaptcha-response"]; const VERIFY_URL = "https://www.google.com/recaptcha/api/siteverify"; // 发起校验请求,参数放到请求体 const googleResp = await fetch(VERIFY_URL, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ secret: CAPTCHA_SECRET_KEY, response: captcha }) }); // 核心步骤:解析JSON响应体 const googleRes = await googleResp.json(); if (googleRes.success) { // v3额外建议:可加一层action和score阈值判断,比如 // if (googleRes.action !== "submit" || googleRes.score < 0.5) return res.status(403).end() const item = await models.ballot.create({ ...tempItem, score: googleRes.score, }); res.status(201).json({ ...item, google: googleRes }); } else { res.status(400).json(googleRes); } } catch (error) { console.log(error); res.status(500).json({ error }); } };
额外排查点:如果修改代码后还是拿不到正常返回,需要确认你的后端服务器可以正常访问Google服务,网络连通性问题也会导致接口调用失败。
内容的提问来源于stack exchange,提问作者Joshua Foxworth
相关产品推荐
相关产品推荐

