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

Next.js API创建用户后发邮件出现ERR_HTTP_HEADERS_SENT错误

问题原因

核心错误原因是接口逻辑中多次向客户端返回响应,Node.js的HTTP协议规则规定:响应一旦发送给客户端后,就不能再修改响应头或发送新的响应内容,否则就会触发ERR_HTTP_HEADERS_SENT报错。具体触发点如下:

  • 用户保存成功后,你先执行了res.send({ user: user._id }),已经完成了一次响应发送
  • 后续代码继续执行发送邮件逻辑后,又调用了res.status(200).json({ status: 'OK' }),尝试第二次发送响应,直接触发报错
  • 如果用户保存触发catch逻辑,你在catch中返回400响应后没有终止代码执行,后续还是会执行发送邮件和第二次返回响应的逻辑,同样会触发报错
解决方案

调整接口逻辑,确保整个请求生命周期内只返回一次响应,修改点如下:

  1. 将发送邮件的逻辑移到try块内,放在用户保存成功之后
  2. 去掉重复的响应发送,邮件发送成功后统一返回一次响应
  3. catch块补全err参数,且返回响应后加return终止后续代码执行

修正后的接口代码如下:

import connectDB from '../../../lib/mongodb'
import bcrypt from 'bcrypt'
import User from '../../../models/user'

const mail = require('@sendgrid/mail');

mail.setApiKey(process.env.SENDGRID_API_KEY);

const handler = async (req, res) => {
  // 检查邮箱是否已存在
  const emailExists = await User.findOne({ email: req.body.email })
  if (emailExists) return res.status(400).send("Email already exists")

  // 加密密码
  const salt = await bcrypt.genSalt(10)
  const hash = await bcrypt.hash(req.body.password, salt)

  const user = new User({
    firstname: req.body.firstname,
    lastname: req.body.lastname,
    username: req.body.username,
    email: req.body.email,
    password: hash
  })

  try {
    const savedUser = await user.save();
    // 发送欢迎邮件
    const message = `
      First Name: ${req.body.firstname}\r\n
      Last Name: ${req.body.lastname}\r\n
      Username: ${req.body.username}\r\n
      Email: ${req.body.email}
    `;

    const data = {
      to: req.body.email,
      from: 'Ellis Development <hello@ebrookes.dev>',
      subject: `Welcome ${req.body.firstname} ${req.body.lastname} to Ellis Development`,
      text: message,
      html: message.replace(/\r\n/g, '<br />')
    };
    await mail.send(data);
    // 统一返回一次响应
    res.status(200).json({ user: savedUser._id, status: 'OK' });
  } catch (err) {
    // 返回错误后终止执行
    return res.status(400).send(err)
  }
}

export default connectDB(handler)

如果不需要等待邮件发送结果再返回响应,可以把await mail.send(data)改为异步非阻塞写法,优化接口响应速度:

mail.send(data).catch(err => console.error('邮件发送失败:', err))

内容的提问来源于stack exchange,提问作者Ben Bagley

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 16:21:00