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

使用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);
}

排查方向与修复方案:

  1. 前端请求缺少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),
    })
    
  2. SMTP配置冲突
    Nodemailer中同时设置service: 'yahoo'和手动host/port会导致配置冲突——service参数会自动覆盖host、port等默认配置,不需要手动指定。删掉冗余的host和port:

    const transport = nodemailer.createTransport({
      service: 'yahoo',
      auth: {
        user: EMAIL,
        pass: PASSWORD,
      },
    });
    
  3. 不要硬编码敏感信息,改用环境变量
    直接把邮箱和密码写在代码里既不安全,也可能因为环境变量未正确加载导致认证失败。

    • 在项目根目录创建.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开发服务器。

  4. 查看服务器端具体错误日志
    前端只看到500,但服务器控制台会输出具体错误信息。启动开发服务器时留意终端输出,比如认证失败、SMTP连接错误等,这是定位问题最直接的方式。

  5. 确认Yahoo应用密码的有效性

    • 确保你的Yahoo账号已经开启了两步验证,应用密码必须在两步验证开启后才能生成。
    • 确认生成的应用密码是用于“邮件”或“SMTP”服务的,不同类型的应用密码权限不同。

先按这几个步骤排查,最可能的问题是前两个——请求头缺失和SMTP配置冲突。

内容的提问来源于stack exchange,提问作者Stephen Welch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 03:53:13