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
相关产品推荐
相关产品推荐

