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

Next.js API路由在cPanel部署后Nodemailer邮件发送异常

cPanel托管Next.js的Nodemailer邮件发送故障排查方案

问题背景

用cPanel托管Next.js站点,开发了/api/mail API路由实现Nodemailer发邮件功能。本地和Vercel部署时功能正常,但在cPanel环境下:

  • 初始调用路由报Internal Server Error,调整async/await后错误消失
  • 接口返回200成功状态,但收件方始终收不到邮件
  • 服务器日志显示SMTP连接相关报错

相关代码

API路由代码

import { NextApiRequest, NextApiResponse } from "next";
import nodemailer from "nodemailer";

type Data = {
  message: string;
};

const handler = async (req: NextApiRequest, res: NextApiResponse<Data>) => {
  const message = {
    from: req.body.email,
    to: "enquiries@domain.com.ng",
    subject: "New Customer Setup",
    text: `${req.body.email} ${req.body.firstname} ${req.body.lastname}`,
    html: `
    <p>Name: ${req.body.firstName} ${req.body.lastName}</p>
    <p>Email: ${req.body.email}</p>
    <p>Phone Number: ${req.body.mobileNumber}</p>
    <p>Residential Address: ${req.body.residentialAddress}</p>
    <p>Gender: ${req.body.gender?.value}</p>
    `,
  };

  const transporter = nodemailer.createTransport({
    secure: true,
    port: 465,
    host: "domain.com.ng",
    auth: {
      user: "enquiries@domain.com.ng",
      pass: "pass",
    },
  });

  try {
    const info = await transporter.sendMail(message);
    console.log(info);
    res.status(200).json({
      message:
        "Thank you for your interest in domain. Our relationship agent will get back to you shortly.",
    });
  } catch (error:any) {
    console.error("Error sending email:", error);
    
    if (error.code === "ECONNREFUSED") {
      res.status(500).json({ message: "Failed to connect to the email server." });
    } else if (error.code === "EAUTH") {
      res.status(500).json({ message: "Invalid email credentials. Authentication failed." });
    } else {
      res.status(500).json({ message: "An error occurred while sending the email." });
    }
  }
};

export default handler;

前端调用代码

const onSubmit = async (data: FormData) => {
    const res = await fetch('/api/mail', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'accept': 'application/json , text/plain, */*'
      },
      body: JSON.stringify(data)

    })
    console.log(res, 'response from server')
    if (res.status === 200) {
      const json = await res.json()
      toast.success(json.message)
      reset()
      router.push('/')
    }
  }

服务器报错日志

- App 9469 output:     at TLSSocket.SMTPConnection._onSocketError (/home2/funditco/nodevenv/frontend_test/16/lib/node_modules/nodemailer/lib/smtp-connection/index.js:194:45)
App 9469 output:     at SMTPConnection._onError (/home2/funditco/nodevenv/frontend_test/16/lib/node_modules/nodemailer/lib/smtp-connection/index.js:780:14)
App 9469 output:     at SMTPConnection. (/home2/funditco/nodevenv/frontend_test/16/lib/node_modules/nodemailer/lib/smtp-transport/index.js:176:24)
App 9469 output:     at /home2/funditco/nodevenv/frontend_test/16/lib/node_modules/nodemailer/lib/mailer/index.js:230:21

故障排查与解决方案

1. 检查cPanel的SMTP端口限制

cPanel服务器通常会限制对外SMTP连接,尤其是465端口。可以尝试:

  • 改用cPanel内置的本地SMTP服务,主机地址设为localhost,端口用25或587
  • 联系主机商核实是否允许外部SMTP服务器出站连接

2. 修正发件人地址合法性

cPanel邮件系统要求from地址必须与认证邮箱一致,否则会被拦截。修改邮件配置:

const message = {
  from: "enquiries@domain.com.ng", // 改为和auth.user一致的邮箱
  replyTo: req.body.email, // 添加回复地址保留用户邮箱
  // 其他字段不变
};

3. 启用Nodemailer调试模式

添加调试参数查看SMTP交互细节,定位具体连接问题:

const transporter = nodemailer.createTransport({
  secure: true,
  port: 465,
  host: "domain.com.ng",
  auth: {
    user: "enquiries@domain.com.ng",
    pass: "pass",
  },
  debug: true, // 开启调试模式
  logger: true // 输出详细交互日志
});

4. 验证邮箱认证信息

确认auth.pass是邮箱的应用专用密码(而非登录密码),部分cPanel邮箱需要开启SMTP认证并使用应用密码登录。

5. 确认Next.js在cPanel的运行配置

  • 确保Next.js以next start命令运行,而非静态导出模式
  • 检查cPanel的Node.js环境是否正确配置了启动指令和端口映射

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 04:35:32