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

使用SendGrid API本地发信正常,部署到域名后无法发送(请求返回200)

部署后SendGrid邮件返回200但未送达的排查与解决

一、检查环境变量加载是否正确

你的代码中加载.env的路径为../.env,部署后服务器目录结构大概率和本地不一致,会导致环境变量无法读取。比如部署时server.js和.env若在同一目录,路径应改为./.env。

  • 解决:调整dotenv.config的路径,或直接在部署平台(如Vercel、Heroku)配置环境变量,不再依赖本地.env文件。
  • 验证:服务器启动时打印process.env.SG_API_KEY、process.env.USER_SENDER、process.env.USER_RECEIVER,确认变量是否正确加载。

二、确认SendGrid发件人邮箱已验证

SendGrid要求发件人邮箱必须完成验证(单邮箱验证或域名验证),否则邮件会被拦截,即使API返回200状态码。

  • 解决:登录SendGrid后台,进入「Sender Authentication」模块,验证process.env.USER_SENDER对应的邮箱或域名。
  • 注意:免费版SendGrid会直接丢弃未验证发件人的邮件,不会进入收件箱或垃圾邮件。

三、修复异步代码逻辑问题

你的代码同时使用await和回调函数,但transport.sendMail在使用回调时不会返回Promise,导致await无效,可能出现错误未被捕获就返回200的情况。

  • 修复示例(以/send_schools_form接口为例):
app.post("/send_schools_form", cors(), async (req, res) => {
  let { school, address, name, phone, email, substitutes } = req.body;

  var substitutesList = substitutes.reduce(function(a, b) {
    return a + '</br><ul><li>Startdatum: ' + b.date + '</li><li>Tid: ' + b.time + '</li><li>Info: ' + b.info + '</li></ul>';
  }, '');

  try {
    await transport.sendMail({
      from: process.env.USER_SENDER,
      to: process.env.USER_RECEIVER,
      subject: "Vikarie begäran",
      html: `
      <ul>
        <li>Skola: ${school}</li>
        <li>Adress: ${address}</li>
        <li>Kontaktperson: ${name}</li>
        <li>Telefon: ${phone}</li>
        <li>E-post: ${email}</li>
      </ul>
      <ul>${substitutesList}</ul>
      `
    });
    res.status(200).send('Success');
  } catch (err) {
    console.log(err);
    res.status(400).send('Error');
  }
});
  • 改用Promise+try/catch的方式,能真实捕获发送过程中的错误,避免错误被隐藏导致返回错误的200状态。

四、完善附件处理的容错逻辑

第二个接口中直接访问req.files["cvFile"][0],若用户未上传对应文件会直接报错,但当前代码的回调无法捕获这个前置错误。

  • 解决:添加文件存在性检查:
// 在sendMail调用前添加
const attachments = [];
if (req.files["cvFile"]?.length > 0) {
  attachments.push({
    filename: req.files["cvFile"][0].originalname,
    content: req.files["cvFile"][0].buffer
  });
}
if (req.files["otherFile"]?.length > 0) {
  attachments.push({
    filename: req.files["otherFile"][0].originalname,
    content: req.files["otherFile"][0].buffer
  });
}

// 然后在sendMail中使用attachments变量
await transport.sendMail({
  // ...其他配置
  attachments: attachments
});

五、查看SendGrid邮件日志

登录SendGrid后台,进入「Email Activity」查看邮件状态,确认邮件是被拦截、退回还是进入垃圾邮件。日志会显示具体原因,比如「Invalid Sender」「Spam Detected」等。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 06:00:59