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

Next.js邮件发送功能报错求助:TypeError与SyntaxError问题

Next.js邮件发送功能调试问题排查

问题概述

调试Next.js项目邮件发送功能时,反复遇到两类错误:

  • TypeError: Cannot destructure property 'email' of 'body' as it is undefined
  • SyntaxError: Unexpected end of JSON input

相关代码如下:

/api/send/route.js

import { NextResponse } from "next/server";
import { Resend } from "resend";

const resend = new Resend(process.env.RESEND_API_KEY);
const fromEmail = process.env.FROM_EMAIL;

export async function POST(req, _res) {
  const { body } = await req.json();

  const { email, subject, message } = body;
  try {
    const data = await resend.emails.send({
      from: fromEmail,
      to: [email],
      subject: subject,
      react: (
        <>
          <h1>{subject}</h1>
<p>Thank you for contancting me!</p>
          <p>new message was submitted:</p>
          <p>{message}</p>
        </>
      ),
    });

    return Response.json(data);
  } catch (error) {
    return Response.json({ status: "fail", error });
  }
}

EmailSection.jsx

/* eslint-disable react/no-unescaped-entities */
"use client";
import React, { useState } from "react";
import Link from "next/link";
import Image from "next/image";
import GitHubIcon from "../../public/images/github.png";
import LinkedInIcon from "../../public/images/linkedin.png";
import DiscordIcon from "../../public/images/discord.png";
import XIcon from "../../public/images/X.png";

const EmailSection = () => {
  const [emailSumitted, setEmailSubmitted] = useState(false);

  const handleSubmit = async (e) => {
    e.preventDefault();
    const data = {
      email: e.target.email.value,
      subject: e.target.subject.value,
      message: e.target.message.value,
    };
    const JSONdata = JSON.stringify(data);
    const endpoint = "/api/send";

    // forming the request for sending data to the server
    const options = {
      method: "POST",

      headers: {
        "Content-Type": "application/json",
      },

      body: JSONdata,
    };

    const response = await fetch(endpoint, options);
    const resData = await response.json();
    console.log(resData);

    if (response.status === 200) {
      console.log("Message sent.");
      setEmailSubmitted(true);
    }
  };

  return (
    <section
      id="contact"
      className="grid md:grid-cols-2 my-12 md:my-12 py-24 gap-4 relative"
    >
      {/* <div className='bg-[radial-gradient(ellipse_at_center,_var(--tw-gradient-stops))] from-purple-900 to-transparent rounded-full h-80 w-80 z-0 blur-lg absolute top-3/4 -left-4 transform -translate-x-1/2 -translate-1/2'></div> */}
      <div className="z-1">
        <h5 className="text-xl font-bold text-white my-2">Let's Connect</h5>
        <p className="text-[#ADB7BE] mb-4 max-w-md">
          {" "}
          Whether it's about the latest tech trends, UI/UX design, or just a
friendly conversation, feel free to reach out!
        </p>
        <div className="socials flex flex-row gap-2">
          <Link href="https://github.com/DiyaVj">
            <Image src={GitHubIcon} className="w-10" alt="Github Icon" />
          </Link>
          <Link href="https://www.linkedin.com/in/diya-vijay/">
            <Image src={LinkedInIcon} className="w-10" alt="LinkedIn Icon" />
          </Link>
          <Link href="https://linktr.ee/Diyavj">
            <Image src={DiscordIcon} className="w-10" alt="Discord Icon" />
          </Link>
          <Link href="https://twitter.com/DiyaVijay6">
            <Image src={XIcon} className="w-10" alt="X Icon" />
          </Link>
        </div>
      </div>
      <div>
        <form className="flex flex-col" onSubmit={handleSubmit}>
          {/* Email  */}
          <div className="mb-6">
            <label
              htmlFor="email"
              className="text-white block mb-2 text-sm font-medium"
            >
              Your email
            </label>
            <input
              name="email"
              type="email"
              id="email"
              required
              className="bg-[#18191E] border border-[#33353F] placeholder-[#9CA2A9] text-gray-100 text-sm rounded-lg block with full p-2.5"
              placeholder="example@gmail.com"
            />
          </div>
          {/* Subject  */}
          <div className="mb-6">
            <label
              htmlFor="subject"
              className="text-white block mb-2 text-sm font-medium"
            >
              Subject
            </label>
            <input
              name="subject"
              type="text"
              id="subject"
              required
              className="bg-[#18191E] border border-[#33353F] placeholder-[#9CA2A9] text-gray-100 text-sm rounded-lg block with full p-2.5"
placeholder="Say Hi or anything you would like to..."
            />
          </div>
          {/* message  */}
          <div className="mb-6">
            <label
              htmlFor="message"
              className="text-white block text-sm mb-2 font-medium"
            >
              Message
            </label>
            <textarea
              name="message"
              id="message"
              className="bg-[#18191E] border border-[#33353F] placeholder-[#9CA2A9] text-gray-100 text-sm rounded-lg block with full p-2.5"
placeholder="Let's talk about..."
            />
          </div>
          {/* button  */}
          <button
            type="submit"
className="bg-gradient-to-r from-purple-400 to-purple-700 hover:bg-gradient-to-r hover:from-slate-800 hover:to-slate-700 text-white font-medium py-2.5 px-5 rounded-lg w-full"
          >
            Send Message
          </button>
          {emailSumitted && (
            <p className="text-green-500 text-sm mt-2">
Email sent successfully!
            </p>
          )}
        </form>
      </div>
    </section>
  );
};

export default EmailSection;

错误原因及修复方案

核心错误:请求体解析错误

req.json()返回的就是完整的请求体对象,你错误地尝试解构body属性,导致解析失败,进而引发两类错误。

修复后的/api/send/route.js

import { NextResponse } from "next/server";
import { Resend } from "resend";

const resend = new Resend(process.env.RESEND_API_KEY);
const fromEmail = process.env.FROM_EMAIL;

export async function POST(req) {
  // 直接获取请求体,无需解构body属性
  const body = await req.json();

  const { email, subject, message } = body;
  try {
    const data = await resend.emails.send({
      from: fromEmail,
      to: [email],
      subject: subject,
      react: (
        <>
          <h1>{subject}</h1>
          <p>Thank you for contacting me!</p>
          <p>new message was submitted:</p>
          <p>{message}</p>
        </>
      ),
    });

    return NextResponse.json(data);
  } catch (error) {
    return NextResponse.json({ status: "fail", error });
  }
}

额外优化点

  1. 统一使用NextResponse.json,避免导入NextResponse却使用原生Response的不一致性
  2. 修复了React邮件模板中的拼写错误contancting改为contacting
  3. 移除了未使用的_res参数

前端可选优化

在handleSubmit中添加错误处理,避免请求失败后仍解析JSON导致额外报错:

const handleSubmit = async (e) => {
  e.preventDefault();
  const data = {
    email: e.target.email.value,
    subject: e.target.subject.value,
    message: e.target.message.value,
  };
  const JSONdata = JSON.stringify(data);
  const endpoint = "/api/send";

  const options = {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSONdata,
  };

  try {
    const response = await fetch(endpoint, options);
    if (!response.ok) throw new Error(`请求失败,状态码:${response.status}`);
    const resData = await response.json();
    console.log(resData);

    setEmailSubmitted(true);
  } catch (error) {
    console.error("发送失败:", error);
    // 可在此添加用户可见的错误提示
  }
};

内容的提问来源于stack exchange,提问作者Diya Vijay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 21:38:13