Next.js/React Form with Cloudflare Turnstile无法从表单中获取响应令牌

bsxbgnwa  于 2022-11-29  发布在  React
关注(0)|答案(1)|浏览(317)

我是NeXT.js/React的新手,我正在尝试构建一个简单的联系人表单,并使用Cloudflare Turnstile保护它。没有Turnstile,我的工作没有任何问题。表单提交到API并发送电子邮件。
环境:
Next.js 13使用“使用客户端”
导入:
从“react”导入{ useState };
从“@marsidev/react-turnstile”导入{十字转门};
但是,现在我尝试使用Turnstile检查表单提交,却无法获得包含响应标记的输入字段。我可以检查表单,看到填写了响应标记的输入字段。下面是我的代码:

表格

<form onSubmit={handleSubmit}>
        <div className="flex flex-col gap-4">
          <div className="form-control w-full max-w-md">
            <label className="label" htmlFor="name">
              <span className="label-text">Name</span>
            </label>
            <input
              type="text"
              id="name"
              placeholder="Your Name"
              required
              className="input w-full max-w-md"
              name="name"
              onChange={(e) => {
                setName(e.target.value);
              }}
            />
          </div>
          <div className="form-control w-full max-w-md">
            <label className="label" htmlFor="email">
              <span className="label-text">Email</span>
            </label>
            <input
              type="text"
              id="email"
              placeholder="Your Email"
              required
              className="input w-full max-w-md"
              name="email"
              onChange={(e) => {
                setEmail(e.target.value);
              }}
            />
          </div>
          <div className="form-control w-full max-w-md">
            <label className="label" htmlFor="subject">
              <span className="label-text">Subject</span>
            </label>
            <input
              type="text"
              id="subject"
              placeholder="Subject"
              required
              className="input w-full max-w-md"
              name="subject"
              onChange={(e) => {
                setSubject(e.target.value);
              }}
            />
          </div>
          <div className="form-control">
            <label className="label" htmlFor="message">
              <span className="label-text">Message</span>
            </label>
            <textarea
              className="textarea-bordered textarea h-48 w-full max-w-md"
              id="message"
              placeholder="Your message"
              required
              name="message"
              onChange={(e) => {
                setMessage(e.target.value);
              }}
            ></textarea>
          </div>
          <Turnstile siteKey={cfSiteKey} />
          <button type="submit" className="btn-primary btn w-full max-w-md">
            Submit
          </button>
        </div>
      </form>

处理程序

let cfSiteKey: string;

  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [subject, setSubject] = useState('');
  const [message, setMessage] = useState('');
  const [submitted, setSubmitted] = useState(false);

  if (process.env.NEXT_PUBLIC_CLOUDFLARE_TURNSTILE_SITE_KEY) {
    cfSiteKey= process.env.NEXT_PUBLIC_CLOUDFLARE_TURNSTILE_SITE_KEY;
  } else {
    throw new Error('Cloudflare Turnstile Secret Key Not Set');
  }
  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    const formData = new FormData();
    const token = formData.get('cf-turnstile-response');
    console.log(token);

    const data = {
      name,
      email,
      subject,
      message,
      token,
    };
    fetch('/api/contact', {
      method: 'POST',
      headers: {
        Accept: 'application/json, text/plain, */*',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data),
    }).then((res) => {
      console.log('Response received');
      if (res.status === 200) {
        console.log('Response succeeded!');
        setSubmitted(true);
        setName('');
        setEmail('');
        setSubject('');
        setMessage('');
      }
    });
  };

在上面,当我提交表单时,token总是返回null。我在这里遗漏了什么或做错了什么?

9jyewag0

9jyewag01#

我想我会回答我的问题。
我在new FormData()内部尝试了很多东西,但是都不起作用。所以我把它留为空白,在我的代码中的其他地方寻找问题。
在处理程序中,答案以及正确的键入如下:

const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const formData = new FormData(e.currentTarget);
    const token = formData.get('cf-turnstile-response') as string;
    console.log(token);

现在,令牌可用并正确发送到API。

相关问题