使用Next.js+Nodemailer提交表单时遭遇500服务器错误求助
问题分析与解决步骤
先贴出你提供的代码:
api/email.ts
import { type NextRequest, NextResponse } from 'next/server'; import nodemailer from 'nodemailer'; import Mail from 'nodemailer/lib/mailer'; export async function POST(request: NextRequest) { const { email, name, message } = await request.json(); const EMAIL ="myEmail"; const PASSWORD="myPassword"; const transport = nodemailer.createTransport({ //setting service as 'gmail' is same as providing these setings: host: "smtp.mail.yahoo.com", port: 465, service: 'yahoo', auth: { user: EMAIL, pass: PASSWORD, }, }); const mailOptions: Mail.Options = { from: EMAIL, to: EMAIL, // cc: email, (uncomment this line if you want to send a copy to the sender) subject: `Message from ${name} (${email})`, text: message, }; const sendMailPromise = () => new Promise<string>((resolve, reject) => { transport.sendMail(mailOptions, function (err) { if (!err) { resolve('Email sent'); } else { reject(err.message); } }); }); try { await sendMailPromise(); return NextResponse.json({ message: 'Email sent' }); } catch (err) { return NextResponse.json({ error: err }, { status: 500 }); } }
utils/send-email.tsx
import { FormData } from '../components/ContactForm'; export function sendEmail(data: FormData) { // TODO: send email const apiEndpoint = '/api/email'; fetch(apiEndpoint, { method: 'POST', body: JSON.stringify(data), }) .then((res) => res.json()) .then((response) => { alert(response.message); }) .catch((err) => { alert(err); }); console.log(data); }
排查方向与修复方案:
前端请求缺少Content-Type头
你的fetch请求没有设置Content-Type: application/json,Next.js的request.json()会因为无法解析请求体而报错,直接导致500。修改send-email.tsx:fetch(apiEndpoint, { method: 'POST', headers: { 'Content-Type': 'application/json', // 加上这个头 }, body: JSON.stringify(data), })SMTP配置冲突
Nodemailer中同时设置service: 'yahoo'和手动host/port会导致配置冲突——service参数会自动覆盖host、port等默认配置,不需要手动指定。删掉冗余的host和port:const transport = nodemailer.createTransport({ service: 'yahoo', auth: { user: EMAIL, pass: PASSWORD, }, });不要硬编码敏感信息,改用环境变量
直接把邮箱和密码写在代码里既不安全,也可能因为环境变量未正确加载导致认证失败。- 在项目根目录创建
.env.local文件:YAHOO_EMAIL=your-yahoo-email@yahoo.com YAHOO_APP_PASSWORD=your-app-password - 修改
api/email.ts读取环境变量:const EMAIL = process.env.YAHOO_EMAIL; const PASSWORD = process.env.YAHOO_APP_PASSWORD;
注意:修改环境变量后需要重启Next.js开发服务器。
- 在项目根目录创建
查看服务器端具体错误日志
前端只看到500,但服务器控制台会输出具体错误信息。启动开发服务器时留意终端输出,比如认证失败、SMTP连接错误等,这是定位问题最直接的方式。确认Yahoo应用密码的有效性
- 确保你的Yahoo账号已经开启了两步验证,应用密码必须在两步验证开启后才能生成。
- 确认生成的应用密码是用于“邮件”或“SMTP”服务的,不同类型的应用密码权限不同。
先按这几个步骤排查,最可能的问题是前两个——请求头缺失和SMTP配置冲突。
内容的提问来源于stack exchange,提问作者Stephen Welch
相关产品推荐
相关产品推荐

