Chromium 122版本下reCaptcha回调未触发的问题求助
Chrome和Edge更新至122版本后,基于Java IceFaces开发的网站出现reCaptcha失效问题:用户点击验证复选框后,加载spinner持续转动,onReCaptchaResponse()和onRecaptchaExpired()回调完全不触发。此前应用运行多年正常,相关实现代码如下:
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async="true" defer="true"> </script> <script type="text/javascript"> var captchaKey = "<the-key>"; //<![CDATA[ function onloadCallback(){ var reCaptchaEl= document.getElementById('re-captcha-main'); grecaptcha.render('reCaptchaEl', { 'sitekey' : captchaKey, 'callback': function () { onReCaptchaResponse(); }, 'expired-callback':function(){ onRecaptchaExpired(); } }); } //]]> </script> <div id="re-captcha-main"></div>
此前旧版本浏览器控制台曾报错:
recaptcha__en.js:191 Uncaught (in promise) TypeError: Iterator value null is not an entry object at new Map (<anonymous>) at E_.X (recaptcha__en.js:191:71) at Array.<anonymous> (recaptcha__en.js:138:3) at f.next (recaptcha__en.js:177:55) at B (recaptcha__en.js:472:261)
122版本后该错误消失,但功能仍异常;禁用chrome://flags/#disable-javascript-harmony-shipping可临时恢复,但并非长久之计。
可行解决方案
修复渲染参数的低级错误
代码中grecaptcha.render('reCaptchaEl', {...})存在明显错误:已经通过document.getElementById获取了DOM元素并存入reCaptchaEl变量,但调用render时却把变量名当成字符串传入,导致reCaptcha无法找到正确的DOM元素完成渲染。修改后代码如下:function onloadCallback(){ var reCaptchaEl= document.getElementById('re-captcha-main'); // 直接传入DOM元素变量,而非字符串 grecaptcha.render(reCaptchaEl, { 'sitekey' : captchaKey, 'callback': function () { onReCaptchaResponse(); }, 'expired-callback':function(){ onRecaptchaExpired(); } }); }这是最可能解决问题的核心修复——之前浏览器可能对这类错误有容错处理,但Chrome/Edge 122的JS引擎严格性提升后,该错误直接导致渲染失败,回调自然无法触发。
升级至reCaptcha v3(长期适配方案)
若v2版本持续遇到浏览器兼容问题,可考虑升级到reCaptcha v3。它采用后台静默验证模式,无需用户手动点击,更适配现代浏览器的JS特性,不过需要后端配合完成响应令牌的验证逻辑。检查IceFaces版本与JS冲突
尝试将IceFaces升级至最新稳定版本,新版本通常会修复现代浏览器的兼容问题。同时排查页面中其他自定义JS代码,是否存在修改Map等全局原生对象的情况——这类操作可能破坏reCaptcha的内部逻辑。
内容的提问来源于stack exchange,提问作者sifo-dias

