如何实现页面加载时触发Invisible reCAPTCHA并解决未定义问题
grecaptcha is not defined问题 嘿,这个问题我太熟悉了!你遇到的核心问题是reCAPTCHA的API脚本是异步加载的(因为你加了async defer),而$(document).ready()只等待DOM结构加载完成,不会等异步脚本加载完毕。直接调用grecaptcha.execute()的时候,Google的脚本可能还没加载好,自然会报错。用setTimeout完全是碰运气,网络慢的时候照样失效,肯定不能这么干。
下面给你两种可靠的解决方案,都是官方推荐或者业界常用的:
方案一:使用reCAPTCHA的onload回调(最推荐)
Google的reCAPTCHA API提供了onload参数,可以指定一个函数,当API脚本完全加载并初始化完成后自动触发。这是最稳妥的方式,完全不需要依赖定时器或者DOM ready。
修改后的完整代码如下:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> </head> <body> <script type="text/javascript"> // 定义reCAPTCHA加载完成后的回调函数 function onRecaptchaLoaded() { grecaptcha.execute(); } var recaptchaCallback = function(token) { alert(token); }; </script> <div class='g-recaptcha' data-sitekey='MY_KEY' data-callback='recaptchaCallback' data-size='invisible'></div> <!-- 引入API时加上onload参数,指定刚才定义的回调 --> <script src="//www.google.com/recaptcha/api.js?onload=onRecaptchaLoaded" async defer></script> </body> </html>
这个方法的原理是:当reCAPTCHA的API脚本加载完成后,会自动调用你指定的onRecaptchaLoaded函数,这时候grecaptcha对象肯定已经存在了,调用execute()不会有任何问题。
方案二:监听grecaptcha对象的存在(备选方案)
如果你因为某些原因不能用onload参数,也可以用一个循环检查grecaptcha是否存在,直到它可用再执行操作。这种方式比定时器更可靠,因为它会实时检查,而不是固定等待时间:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> </head> <body> <script type="text/javascript"> var recaptchaCallback = function(token) { alert(token); }; $(document).ready(function(){ // 定义检查函数 function checkRecaptcha() { if (typeof grecaptcha !== 'undefined') { grecaptcha.execute(); } else { // 每隔100ms检查一次,直到grecaptcha可用 setTimeout(checkRecaptcha, 100); } } checkRecaptcha(); }); </script> <div class='g-recaptcha' data-sitekey='MY_KEY' data-callback='recaptchaCallback' data-size='invisible'></div> <script src="//www.google.com/recaptcha/api.js" async defer></script> </body> </html>
这种方式会在DOM ready后开始循环检查,一旦grecaptcha对象存在就立即执行execute(),比固定1秒的定时器灵活得多,不会浪费时间也不会因为网络慢而失效。
总结一下,方案一是首选,因为它是Google官方提供的加载完成回调机制,最符合reCAPTCHA的设计逻辑,稳定性拉满。
内容的提问来源于stack exchange,提问作者user1111929

