在React中添加EmailJS reCaptcha验证

问题描述 投票:0回答:3

我正在尝试在我的代码中添加 EmailJS reCaptcha 验证。 我已阅读文档,但我不明白如何应用它,也没有找到任何示例。

function Register() {

    const [open, setOpen] = useState(false);

    const [toSend, setToSend, ] = useState({
        azienda: '',
        email: '',
        piva: '',
        codicefiscale: '',
    });

    const handleSubmit=(e)=>{
        e.preventDefault();
        send(
            'service_****',
            'template_*****',
            toSend,
            '************',
            'g-recaptcha-response'
        )
            .then((response) => {
                setOpen(true);
            })
    };

    const handleChange = (e) => {
        setToSend({...toSend, [e.target.name]: e.target.value });
    };

表单中提交按钮上方:

<ReCAPTCHA       
 sitekey='**********'
/>

我在提交表单时收到此错误:

reactjs recaptcha
3个回答
0
投票

我遇到了同样的问题,并且能够克服它。

为了在启用 EmailJS Recaptcha (V2) 设置的情况下成功发送电子邮件,您需要执行以下操作:

  • 在您的代码中向验证码添加一个
    useRef
    挂钩。我在下面的示例中将其命名为
    refCaptcha
    (不要忘记从
    useRef
    导入
    'react'
  • 在您的
    ref={refCaptcha}
    组件中添加
    <ReCAPTCHA />
    (见下文)。
  • 在您的
    handleSubmit()
    函数内,在
    e.preventDefault()
    下方,您必须从验证码中获取值,您可以这样做
    refCaptcha.current.getValue();
    ,请参阅下面的示例,查看我如何将其保存到此
    token
    const。
  • 然后你必须创建这个对象,我将其命名为
    params
    并将你的
    toSend
    状态展开到其上,并向其添加
    'g-recaptcha-response': token
    ,请参见下面的示例。
  • 然后在您的
    emailjs.send()
    方法中,添加我们刚刚创建的
    params
    对象作为第三个参数,而不是直接添加
    toSend
    状态,再次在下面的示例中检查它。
function Register() {

    const refCaptcha = useRef(); // <- add the useRef hook

    const [open, setOpen] = useState(false);

    const [toSend, setToSend, ] = useState({
        azienda: '',
        email: '',
        piva: '',
        codicefiscale: '',
    });

    const handleSubmit=(e)=>{
        e.preventDefault();
    
        const token = refCaptcha.current.getValue(); // <- `getValue()` from the instantiated refCaptcha
    
        const params = {
          ...toSend,
          'g-recaptcha-response': token,
        }; // <- Create this object spreading your state and adding the retrieved token as a value of 'g-recaptcha-response'
    
        emailjs.send(
            'service_****',
            'template_*****',
            params, // <- Replace your state with this params object that contains the g-recaptcha-response key/value with the token retrieved.
            '************',
            'g-recaptcha-response'
        )
            .then((response) => {
                setOpen(true);
            },
            (err) => {
              console.log('EMAILJS ERROR', err);
            })
    };

    const handleChange = (e) => {
        setToSend({...toSend, [e.target.name]: e.target.value });
    };
    return (

        <form onSubmit={handleSubmit}>
          ...
        <ReCAPTCHA ref={refCaptcha} sitekey={process.env.REACT_APP_SITE_KEY} />
        // add the ^^ `ref={refCaptcha}` into your ReCAPTCHA component
        </form>
    )
  };

我刚刚在这里进行了测试,并且能够使用启用了 Recaptcha (V2) 的 EmailJS 发送电子邮件,执行上述步骤。

我能够收集一些信息来解决这个问题(这些链接中没有解决方案,只有一些导致此解决方案的小部分):


0
投票

我不确定我的答案是否适用于这个问题,因为我使用了隐形的 ReCaptcha。但我收到了完全相同的错误消息,并最终来到这里寻找答案。 就我而言,由于不可见属性,网站用户没有通过单击“我不是机器人”来提示验证码验证,因此需要以编程方式执行验证码来获取令牌。 我想出了以下解决方案。

  const Form = () => {
    //form answers are saved as templateParams
    const [templateParams, setTemplateParams] = useState({
      azienda: '',
      email: '',
      piva: '',
      codicefiscale: '',});
      //reference to recaptcha
      const recaptchaRef = React.useRef<ReCAPTCHA>(null);

      //setting the form params on input change     
      const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        setTemplateParams({...templateParams, [e.taget.name]: e.target.value});
      }
      
     const submitInput = (token) => {} //see declaration below

     //executing captcha on formsubmit
     const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
       e.preventDefault();
       const token = await recaptchaRef.current.executeAsync(); //executeAsync executes the captcha and awaits the result if user input is required. 
       token && submitInput(token); //when the token is ready, the actual submit function is called

      return (
        <form onSubmit={handleSubmit}>
          <ReCAPTCHA
            ref={recaptchaRef}
            size="invisible" //removing the 'I'm not a robot' box
            sitekey={process.env.PUBLICRECAPTCHAKEY}
          <input name='azienda' onChange={handleChange} />
          ...
        </form>
        )
    }

表单数据已保存在状态中并且验证码已被执行 - 这意味着如果存在可疑行为,则会要求用户完成拼图。一旦令牌可用,就会调用以下函数:

  const submitInput = (token: string | null) => {
    const params = {
      ...templateParams,
      'g-recaptcha-response': token
  }
  emailjs.send(
    'your_service_name',
    'your_template_name',
    params,
    'g-recaptcha-response': token
    )
    .then(() => {
      recaptchaRef.current.reset(); // resetting captcha so it has to be completed again before sending a new message
    }, err => {
    console.error(err)
    //and inform the user that submission failed
  }
  }

0
投票

我最终将提交操作放入作为 ReCAPTCHA 回调触发的 recaptchaOnChange 函数中 - 参见react-google-recaptcha

作为不可见的 ReCaptcha,您必须在按下提交按钮时使用

recaptchaRef.current.execute();
手动执行它。

这是代码:

import { useRef} from "react";
import emailjs from "@emailjs/browser";
import ReCAPTCHA from "react-google-recaptcha";

export default function Form() {
  const form = useRef();
  const recaptchaRef = useRef();

  function recaptchaOnChange(value) {
    const formData = {
      name: form.current.elements.name.value,
      email: form.current.elements.email.value,
      message: form.current.elements.message.value,
      privacy: form.current.elements.privacy.checked,
      "g-recaptcha-response": value,
    };
    emailjs
      .send(
        process.env.REACT_APP_EMAILJS_SERVICE_ID,
        process.env.REACT_APP_EMAILJS_TEMPLATE_ID,
        formData,
        process.env.REACT_APP_EMAILJS_PUBLIC_KEY
      )
      .then(
        (result) => {
          recaptchaRef.current.reset();
        },
        (error) => {
          console.log(error.text);
        }
      );
  }

  const sendEmail = (e) => {
    e.preventDefault();
    recaptchaRef.current.execute();
  };

  return (
      <form
        ref={form}
        onSubmit={sendEmail}
      >
        <label>Name</label>
        <input
          type="text"
          name="name"
          required="required"
        />
        <label>Email</label>
        <input
          type="email"
          name="email"
          required="required"
        />
        <label>Messaggio</label>
        <textarea
          name="message"
          rows="5"
          required="required"
        />
        <div className="checkbox">
          <input
            type="checkbox"
            name="privacy"
            value="privacy policy"
            required="required"
          />
          <p>
            privacy policy
          </p>
        </div>
        <ReCAPTCHA
          ref={recaptchaRef}
          sitekey={process.env.REACT_APP_RECAPTCHA_SITE_KEY}
          size="invisible"
          onChange={recaptchaOnChange}
        />
        <input
          type="submit"
          value="Send"
        />
      </form>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.