如何在TypeScript版React项目中使用captcha.com的Botdetect Captcha?
在React + TypeScript中集成Botdetect Captcha的解决方案
1. 手动补充类型声明(解决TS编译错误)
官方没有提供React环境的TypeScript类型定义,你需要手动创建类型声明文件来消除编译报错:
在项目根目录或src文件夹下创建botdetect.d.ts:
declare global { interface Window { BotDetectCaptcha: { init(settings: { id: string; theme?: string; inputName?: string; // 根据你用到的配置补充其他字段 }): void; getInstance(captchaId: string): { getCaptchaId(): string; validate(userInput: string): Promise<boolean>; // 按需添加你需要调用的其他方法 }; }; } } export {};
2. 封装函数式Captcha组件(替代类组件的this问题)
用useRef保存Captcha实例,替代类组件中的this,同时封装你需要的getInstance()和getCaptchaId()方法:
创建BotdetectCaptcha.tsx组件:
import { useEffect, useRef, forwardRef, useImperativeHandle } from 'react'; interface BotdetectCaptchaProps { captchaId: string; theme?: string; inputName?: string; } // 定义父组件可调用的方法类型 interface CaptchaMethods { getInstance: () => typeof window.BotDetectCaptcha.getInstance extends (id: string) => infer T ? T : null; getCaptchaId: () => string | undefined; } export const BotdetectCaptcha = forwardRef<CaptchaMethods, BotdetectCaptchaProps>((props, ref) => { const { captchaId, theme = 'light', inputName = `${captchaId}-user-input` } = props; const captchaInstanceRef = useRef<ReturnType<typeof window.BotDetectCaptcha.getInstance> | null>(null); useEffect(() => { // 初始化Captcha window.BotDetectCaptcha.init({ id: captchaId, theme, inputName }); // 保存实例到ref captchaInstanceRef.current = window.BotDetectCaptcha.getInstance(captchaId); // 清理逻辑(如果需要) return () => { // 若有销毁方法可在此调用,比如 captchaInstanceRef.current?.destroy() }; }, [captchaId, theme, inputName]); // 暴露方法给父组件 useImperativeHandle(ref, () => ({ getInstance: () => captchaInstanceRef.current, getCaptchaId: () => captchaInstanceRef.current?.getCaptchaId() })); return ( <div className="captcha-container"> <div id={captchaId}></div> <input type="text" name={inputName} placeholder="输入验证码" /> </div> ); }); BotdetectCaptcha.displayName = 'BotdetectCaptcha';
3. 在父组件中使用并调用方法
通过useRef获取子组件实例,调用你需要的方法:
import { useRef } from 'react'; import { BotdetectCaptcha } from './BotdetectCaptcha'; const LoginForm = () => { const captchaRef = useRef<CaptchaMethods>(null); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); const captchaInstance = captchaRef.current?.getInstance(); const captchaId = captchaRef.current?.getCaptchaId(); if (captchaInstance && captchaId) { // 示例:获取用户输入并验证 const userInput = (e.currentTarget as HTMLFormElement).querySelector(`[name="${captchaId}-user-input"]`) as HTMLInputElement; const isValid = await captchaInstance.validate(userInput.value); console.log('验证码验证结果:', isValid); } }; return ( <form onSubmit={handleSubmit}> <BotdetectCaptcha ref={captchaRef} captchaId="login-captcha" /> <button type="submit">提交</button> </form> ); };
4. 引入官方脚本
在public/index.html的<head>或<body>末尾添加Botdetect的CDN脚本:
<script src="https://cdn.captcha.com/js/botdetect/v4/botdetect-captcha.min.js"></script>
额外注意事项
- 原
captcha-settings.js中的配置可以直接作为props传入组件,无需单独维护JS文件 captcha-helper.js中的工具函数可以转成TypeScript函数,比如验证码验证逻辑可以整合到父组件或单独的工具文件中
内容的提问来源于stack exchange,提问作者Aliasghar Yaghoobzadeh
相关产品推荐
相关产品推荐

