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

如何获取reCAPTCHA Token?无需React npm包实现方案咨询

问题

我想获取向Google reCAPTCHA的siteverify接口发送请求所需的Token,官方文档说的不够清楚,而且我不想用React相关的npm包,觉得这点功能没必要依赖第三方。

我写了一段React代码,但不知道怎么拿到reCaptcha Token,怀疑是Google脚本或者提交按钮的配置有问题,也不确定Token是不是在表单事件里,之前听说可以用grecaptcha.getResponse()但没找到示例,求技术指导。

原代码:

const MyPage = () => {

  const [reCaptchaVerified, setReCaptchaVerified] = useState(false);

  const handleSubmit = (event) => {

    let captchaToken = '';                                          // 怎么拿到reCaptcha Token?
    let captchaResult = GoogleReCaptcha(captchaToken);              // 我的后端接口,负责把token和密钥发给Google的API
    
    if(captchaResult === true){
        setReCaptchaVerified(true);
    }
    else {
        setReCaptchaVerified(false);
    }
  }

  return (
    <form id="my-form" onSubmit="handleSubmit()">
        <button type="submit" disabled={!reCaptchaVerified} data-sitekey={ RECAPTCHA_SITE_KEY } data-callback='onSubmit' data-action='my-form-submit'>Submit</button>
    </form>
    <footer>
        {/* Google ReCaptcha Script  */}
        <Script src="https://www.google.com/recaptcha/api.js"></Script>
        <Script>
            {`function onSubmit(token) {
                document.getElementById("my-form").submit();
            } `}
        </Script>
    </footer>
  )
}

解决方案

你的代码目前有几个关键问题:

  • 表单onSubmit用了字符串写法,React里得传函数引用
  • 按钮的data-callback指向全局函数,和组件内部逻辑脱节,没法把Token拿到组件里用
  • 按钮提前禁用的逻辑不对,reCaptchaVerified应该是验证通过后才更新的状态

下面是正确的实现方式:

修改后的完整代码

import { useState, useEffect } from 'react';

const MyPage = () => {
  const [reCaptchaToken, setReCaptchaToken] = useState('');
  const [isVerified, setIsVerified] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);

  // 动态加载reCAPTCHA脚本,确保全局grecaptcha对象可用
  useEffect(() => {
    if (window.grecaptcha) return;
    const script = document.createElement('script');
    // 带上render参数,提前加载对应site key的资源
    script.src = `https://www.google.com/recaptcha/api.js?render=${RECAPTCHA_SITE_KEY}`;
    script.async = true;
    script.defer = true;
    document.body.appendChild(script);

    script.onload = () => {
      window.grecaptcha.ready(() => {
        console.log('reCAPTCHA加载完成');
      });
    };

    // 组件卸载时移除脚本,避免内存泄漏
    return () => document.body.removeChild(script);
  }, []);

  // 处理验证+提交逻辑
  const handleSubmit = async () => {
    setIsSubmitting(true);
    try {
      // 核心:调用grecaptcha.execute获取Token
      const token = await window.grecaptcha.execute(RECAPTCHA_SITE_KEY, { 
        action: 'my-form-submit' // 和你之前定义的action保持一致
      });
      setReCaptchaToken(token);

      // 调用后端验证接口,必须异步处理网络请求
      const captchaResult = await GoogleReCaptcha(token);
      if (captchaResult) {
        setIsVerified(true);
        // 验证通过后提交表单
        document.getElementById('my-form').submit();
      } else {
        setIsVerified(false);
        alert('reCAPTCHA验证失败,请重试');
      }
    } catch (error) {
      console.error('验证出错:', error);
      setIsVerified(false);
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <>
      <form id="my-form">
        {/* 这里放你的表单输入字段 */}
      </form>
      <button 
        onClick={handleSubmit} 
        disabled={isSubmitting}
      >
        {isSubmitting ? '验证中...' : '提交'}
      </button>
    </>
  );
};

export default MyPage;

关键说明

  • 获取Token的核心方法:window.grecaptcha.execute(siteKey, { action: 'xxx' }),这个方法返回Promise,直接拿到Token,比grecaptcha.getResponse()更适配React的异步状态管理
  • 脚本加载优化:用useEffect动态加载,避免页面初始化时阻塞,同时确保脚本只加载一次
  • 去掉全局回调:所有逻辑都在组件内部处理,不再依赖全局函数,更符合React的状态管理习惯
  • 异步处理:后端验证接口必须用async/await或Promise处理,网络请求不能同步调用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 04:54:57