React集成invisible reCaptcha v3后出现UnhandledRejection超时报错求助
解决React集成reCaptcha v3后出现的UnhandledRejection: Timeout报错
问题原因
你全局加载reCaptcha脚本后,即便用户在非登录页操作,reCaptcha仍会在后台尝试和Google服务建立连接。当用户网络环境差、有防火墙限制时,这个请求会超时并抛出未被捕获的Promise拒绝——而你只在登录页处理了reCaptcha相关逻辑,其他路由没做错误捕获,所以Sentry抓了这个报错。
解决方案
1. 改为登录页按需加载脚本(最彻底)
不要全局打包加载reCaptcha脚本,只在登录组件里动态加载,组件卸载时清理,避免非登录页产生不必要的后台请求:
import { useEffect } from 'react'; const LoginPage = () => { useEffect(() => { const script = document.createElement('script'); script.src = `https://www.google.com/recaptcha/api.js?render=你的siteKey`; script.async = true; script.defer = true; document.body.appendChild(script); return () => { document.body.removeChild(script); // 可选:清理全局的grecaptcha对象,避免残留 if (window.grecaptcha) { delete window.grecaptcha; } }; }, []); // 登录逻辑和reCaptcha调用... }; export default LoginPage;
2. 全局捕获reCaptcha超时错误(适合无法改加载方式的场景)
如果必须全局加载脚本,在应用入口添加全局监听,过滤掉reCaptcha相关的超时拒绝:
// 比如在index.js里 window.addEventListener('unhandledrejection', (event) => { // 匹配reCaptcha的超时错误 if (event.reason === 'Timeout' && window.grecaptcha) { event.preventDefault(); // 阻止Sentry捕获该错误 } });
3. 给登录页的reCaptcha调用加超时处理
在调用grecaptcha.execute时,用Promise.race手动设置超时,主动捕获错误,避免未处理的拒绝:
const getRecaptchaToken = async () => { // 5秒超时的Promise const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('reCaptcha 请求超时')), 5000); }); try { const token = await Promise.race([ window.grecaptcha.execute('你的siteKey', { action: 'login' }), timeoutPromise ]); return token; } catch (err) { // 这里处理错误,比如提示用户检查网络 console.error('reCaptcha 执行失败:', err); return null; } };
内容的提问来源于stack exchange,提问作者Sumit
相关产品推荐
相关产品推荐

