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

MERN+TypeScript项目调用reCAPTCHA v3遇Invalid listener错误

解决reCAPTCHA "Invalid listener argument" 错误

错误原因

你遇到的Invalid listener argument错误,根源是错误地将grecaptcha.ready()当作返回Promise的函数使用。原生的reCAPTCHA ready()方法只接受一个回调函数作为参数,并不返回Promise。当你用await grecaptcha.ready()调用时,相当于没有传入任何有效监听函数(实际传入的是undefined),触发了底层的参数校验错误。

解决方案

需要将grecaptcha.ready()包装为Promise,才能用async/await语法调用,同时修正类型声明和脚本加载逻辑避免冲突。

1. 修正reCAPTCHA工具函数

修改utils/recaptchaUtils.ts,把ready()包装成Promise,并添加精确的类型声明:

// utils/recaptchaUtils.ts
declare const grecaptcha: {
  ready: (callback: () => void) => void;
  execute: (siteKey: string, options: { action: string }) => Promise<string>;
};

export const executeRecaptcha = async (action = 'submit') => {
    const siteKey = process.env.REACT_APP_RECAPTCHA_SITE_KEY;
    if (!grecaptcha || !siteKey) {
        console.error("reCAPTCHA library or site key not available");
        return;
    }

    try {
        // 将ready方法包装为Promise
        await new Promise<void>(resolve => grecaptcha.ready(resolve));
        return await grecaptcha.execute(siteKey, { action });
    } catch (error) {
        console.error("reCAPTCHA error:", error);
    }
};

2. 优化脚本加载逻辑

修改App.tsx中的脚本加载代码,避免重复加载并清理全局变量:

// App.tsx
// ...
declare const grecaptcha: {
  ready: (callback: () => void) => void;
};

function App() {
  useEffect(() => {
    const scriptId = 'recaptcha-script';
    // 避免重复插入脚本
    if (document.getElementById(scriptId)) return;

    const script = document.createElement('script');
    script.id = scriptId;
    script.src = `https://www.google.com/recaptcha/api.js?render=${process.env.REACT_APP_RECAPTCHA_SITE_KEY}`;
    script.async = true;
    script.defer = true;
    script.onload = () => {
      console.log('reCAPTCHA library loaded.');
    };
    document.head.appendChild(script);

    return () => {
      const existingScript = document.getElementById(scriptId);
      if (existingScript) {
        document.head.removeChild(existingScript);
        // 清除全局grecaptcha变量,避免下次加载冲突
        (window as any).grecaptcha = undefined;
      }
    };
  }, []);
// ...

额外检查点

  • 确认环境变量REACT_APP_RECAPTCHA_SITE_KEY已正确注入:可以在控制台打印process.env.REACT_APP_RECAPTCHA_SITE_KEY验证。
  • 不要在多个地方重复调用grecaptcha.ready(),统一通过工具函数处理即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 03:11:23