Next.js邮件发送功能报错求助:TypeError与SyntaxError问题
Next.js邮件发送功能调试问题排查
问题概述
调试Next.js项目邮件发送功能时,反复遇到两类错误:
TypeError: Cannot destructure property 'email' of 'body' as it is undefinedSyntaxError: 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 }); } }
额外优化点
- 统一使用
NextResponse.json,避免导入NextResponse却使用原生Response的不一致性 - 修复了React邮件模板中的拼写错误
contancting改为contacting - 移除了未使用的
_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
相关产品推荐
相关产品推荐

