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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 18:05:19