我需要在我的表单中实现recaptcha,但我不知道如何正确地做到这一点。
问题是 recaptcha 是异步的,当它处于不可见模式时,令牌几乎可以立即使用,但是当用户必须选择交通灯时,可能需要一段时间。
如何延迟发送表单,以便它可以等待令牌值并使用 onSubmit 将服务器端验证错误返回到表单?
也许我应该使用 react-google-recaptcha 以外的其他东西?
下面是一种可行的方法,但它看起来也很老套,应该有更好的方法来做到这一点。
function FormBuilder(props: FormBuilderProps): ReactElement<FormBuilderProps> {
const recaptchaRef = React.createRef()
const getCaptchaCode = async () => {
return new Promise(((resolve, reject) => {
recaptchaRef.current.execute();
let counter = 0;
// Wait for captcha value to appear
const checker = setInterval(()=>{
const value = recaptchaRef.current.getValue();
counter++;
if (value) {
clearInterval(checker);
resolve(value);
}
// kill form submition after couple of minutes (how does it take to select all the traffic ligths :))
if (counter > 600) {
clearInterval(checker);
reject();
}
}, 500);
}))
}
const onFormSubmit = async (values) => axios
.post(target, {
captcha: await getCaptchaCode(),
...values,
})
.catch((error) => {
return handleSubmitErrors(error);
})
return (
<Form
onSubmit={onFormSubmit}
render={({
handleSubmit,
submitting,
}) => {
return (
<form>
{/* form fields */}
<ReCAPTCHA
size="invisible"
sitekey={config.getReCaptchaSiteKey()}
ref={recaptchaRef}
asyncScriptOnLoad={() => {
setRecaptchaLoaded(true);
}}
/>
<Submit
handleSubmit={handleSubmit}
submitting={submitting}
/>
</form>
)
}}
/>
)
}
``