You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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时触发了浏览器跨域安全限制,尤其在构建产物嵌入其他域名页面时容易出现,可按以下步骤修复:

  1. 移除脚本手动清理逻辑
    不要在组件卸载时执行document.body.removeChild(script),手动移除脚本会导致reCAPTCHA的iframe与脚本上下文断开,引发跨域访问异常,让浏览器自动管理脚本资源即可。

  2. 优化脚本加载逻辑
    避免重复创建脚本标签,确保脚本加载与渲染逻辑的上下文绑定正确:

    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);
    };
    
  3. 补全reCAPTCHA白名单域名
    除localhost外,需将嵌入构建产物的目标应用域名也添加到reCAPTCHA控制台的允许域名列表中,reCAPTCHA会验证父页面域名是否在白名单内。

  4. 简化captchaRef操作
    修改reset逻辑,避免不必要的对象解构,保持引用稳定性:

    if (captchaRef.current.captcha) {
        captchaRef.current.pendingCaptcha = true;
        window.grecaptcha.reset(captchaRef.current.captcha);
    }
    

内容的提问来源于stack exchange,提问作者Kamran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 06:15:10