Vite-React-TS集成Google reCAPTCHA跨域框架报错求助
在嵌入第三方页面时,Google reCAPTCHA 跨域帧访问被阻止问题
问题背景
我在Vite-React-TS项目中集成了Google reCAPTCHA并完成构建,将构建产物通过script标签加载到其他应用中时,出现跨域错误。
实现代码
动态加载reCAPTCHA脚本
const script = document.createElement('script'); script.src = url; script.async = true; script.defer = true; script.onload = renderCaptcha; document.body.appendChild(script); return () => { document.body.removeChild(script); }
渲染reCAPTCHA逻辑
const renderCaptcha = () => { if (window?.grecaptcha) { try { if (captchaRef.current.captcha) { captchaRef.current = { ...captchaRef.current, pendingCaptcha: true }; window?.grecaptcha.reset(captchaRef.current.captcha); } else { const captcha = window?.grecaptcha.render(captchaContainerRef.current, { sitekey: CAPTCHA_V2_KEY, callback: () => { captchaRef.current = { ...captchaRef.current, pendingCaptcha: false }; }, 'expired-callback': (data: any) => { console.log("expired") console.log(data) }, 'error-callback': (error: any) => { console.log("error") console.log(error) } }); captchaRef.current = { ...captchaRef.current, captcha, pendingCaptcha: true }; } } catch (e) { console.error('captcha generation error', e); } } };
JSX容器
<div ref={captchaContainerRef} id="signin_captcha" />
错误信息
Uncaught DOMException: Blocked a frame with origin "https://www.google.com" from accessing a cross-origin frame.
当前环境
- 本地使用带SSL的http-server运行项目
- 已在reCAPTCHA控制台将localhost加入白名单
需求
让reCAPTCHA能在嵌入第三方页面时正常加载运行
解决方案
这个错误是reCAPTCHA的iframe尝试访问父页面DOM时触发了浏览器跨域安全限制,尤其在构建产物嵌入其他域名页面时容易出现,可按以下步骤修复:
移除脚本手动清理逻辑
不要在组件卸载时执行document.body.removeChild(script),手动移除脚本会导致reCAPTCHA的iframe与脚本上下文断开,引发跨域访问异常,让浏览器自动管理脚本资源即可。优化脚本加载逻辑
避免重复创建脚本标签,确保脚本加载与渲染逻辑的上下文绑定正确:const loadCaptchaScript = () => { if (window.grecaptcha) { renderCaptcha(); return; } const existingScript = document.querySelector(`script[src="${url}"]`); if (existingScript) { existingScript.addEventListener('load', renderCaptcha); return; } const script = document.createElement('script'); script.src = url; script.async = true; script.defer = true; script.addEventListener('load', renderCaptcha); document.body.appendChild(script); };补全reCAPTCHA白名单域名
除localhost外,需将嵌入构建产物的目标应用域名也添加到reCAPTCHA控制台的允许域名列表中,reCAPTCHA会验证父页面域名是否在白名单内。简化captchaRef操作
修改reset逻辑,避免不必要的对象解构,保持引用稳定性:if (captchaRef.current.captcha) { captchaRef.current.pendingCaptcha = true; window.grecaptcha.reset(captchaRef.current.captcha); }
内容的提问来源于stack exchange,提问作者Kamran
相关产品推荐
相关产品推荐

