Nodemailer在cPanel虚拟主机无法发邮件,本地及Render正常求助
Nodemailer在cPanel虚拟主机无法发送邮件,本地和Render主机正常
问题描述
使用Nodemailer给客户发送邮件时,部署到带cPanel的虚拟主机后无法发送,但本地环境和Render主机上能正常运行。已确认应用可读取.env文件,也重启过应用,问题仍存在。是否需要更换其他Node.js邮件库?
原始发送邮件代码
const transporter = mailer.createTransport({ service: "gmail", auth: { user: process.env.MAIL, pass: process.env.MAIL_PASS, }, }); app.post("/send", (req, res) => { const data = { name: req.body.name, mail: req.body.mail, phone: req.body.phone, msg: req.body.msg, title: "new message form contact section", }; if (data.phone.length == 0) { data["phone"] = "not given!"; } ejs.renderFile("./views/mail.ejs", data, function (err, ejsout) { transporter.sendMail({ from: process.env.MAIL, to: "***********@gmail.com", subject: "Support request 👮♂️", html: ejsout, }); res.render("msg", { msg: "Message was send successfully!" }); }); });
编辑后的代码(添加错误处理)
更新代码后,虚拟主机运行时返回错误提示,但Render主机仍显示发送成功:
ejs.renderFile("./views/mail.ejs", data, async function (err, ejsout) { await new Promise((resolve, reject) => { transporter.sendMail( { from: process.env.MAIL, to: "*********@gmail.com", subject: "Support request 👮♂️", html: ejsout, }, (err, info) => { if (err) { res.render("msg", { msg: "Error there is a problem sending your message! Please Contact us via Email.", }); } else { res.render("msg", { msg: "Message was send successfully!" }); } } ); }); });
解决方案
1. 排查cPanel主机的端口限制
大部分cPanel虚拟主机会封禁SMTP默认端口(比如Gmail常用的465/587),这是最常见的原因:
- 查看主机商文档,确认允许使用的SMTP端口;
- 改用主机自带邮件服务,配置transporter时使用cPanel提供的SMTP信息(主机地址一般为
mail.yourdomain.com,端口25/587,账号密码用你在cPanel创建的邮箱信息)。
2. 验证Gmail授权配置
如果坚持使用Gmail,注意以下几点:
- 2022年后普通密码无法用于第三方应用,必须启用应用专用密码(前提是账号开启两步验证);
- 未开启两步验证的话,可临时开启不太安全的应用访问(不推荐长期使用);
- 去Google账号安全中心检查是否有陌生IP的登录拦截提醒,手动允许该主机IP访问。
3. 修复代码的异步逻辑问题
你编辑后的代码存在Promise未正确resolve/reject的问题,会导致请求挂起,正确写法如下:
ejs.renderFile("./views/mail.ejs", data, async function (err, ejsout) { if (err) { return res.render("msg", { msg: "模板渲染失败,请稍后重试" }); } try { await transporter.sendMail({ from: process.env.MAIL, to: "*********@gmail.com", subject: "Support request 👮♂️", html: ejsout, }); res.render("msg", { msg: "Message was send successfully!" }); } catch (err) { // 打印错误日志到控制台,方便排查具体问题 console.error(err); res.render("msg", { msg: "Error there is a problem sending your message! Please Contact us via Email.", }); } });
修改后可以在cPanel的应用日志中查看具体错误信息,定位是端口封禁、授权失败还是其他问题。
4. 无需急于更换邮件库
Nodemailer是Node.js生态中最成熟的邮件库,问题大概率出在主机配置或授权环节,而非库本身。如果以上方法都无效,可以尝试SendGrid、Mailgun等第三方邮件服务,它们的端口一般不会被主机封禁,配置也更简单。
内容的提问来源于stack exchange,提问作者Mohammed Zaky
相关产品推荐
相关产品推荐

