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

Express.js + Nodemailer在Vercel生产环境无法发送邮件求助

开发环境正常、Vercel生产环境失效的Nodemailer问题排查与解决

以下针对你遇到的问题,结合给出的代码逐一分析可能的原因及解决方案:

1. 环境变量与配置文件未同步

你的代码混合了process.env环境变量和本地gmail.js配置文件,Vercel生产环境无法读取本地配置文件,且环境变量可能未正确部署:

  • 把gmail.js中的clientId、clientSecret、refreshToken全部迁移到Vercel项目的「环境变量」中(项目设置→Environment Variables),代码中直接通过process.env读取:
    auth: {
      type: "OAuth2",
      user: process.env.MAIL_USERNAME,
      pass: process.env.APP_PASSWORD,
      clientId: process.env.GMAIL_CLIENT_ID,
      clientSecret: process.env.GMAIL_CLIENT_SECRET,
      refreshToken: process.env.GMAIL_REFRESH_TOKEN,
      // 建议移除accessToken,让Nodemailer自动通过refreshToken刷新,避免令牌过期
    },
    
  • 修改环境变量后重新部署Vercel项目,确保变量生效。

2. 邮件模板文件路径错误

本地开发的目录结构和Vercel部署后的结构不一致,path.join(__dirname, '../../src/templates/email/${data.template}')可能找不到模板文件,导致fs.readFileSync抛出错误:

  • 改用异步读取并添加错误捕获,避免同步读取阻塞流程且无错误提示:
    // 替换原同步读取代码
    fs.readFile(filePath, "utf8", (err, fileTemplate) => {
      if (err) {
        return reject(new Error(`读取邮件模板失败: ${err.message}`));
      }
      const mailOptions = {
        from: '"Event Organizing" <arkawebdev1@gmail.com>',
        to: data.to,
        subject: data.subject,
        html: mustache.render(fileTemplate, { ...data }),
      };
      transporter.sendMail(mailOptions, (error, result) => {
        error ? reject(error) : resolve(result);
      });
    });
    
  • 同时检查Vercel部署后的文件结构,确保模板文件被正确打包到生产环境(可在Vercel部署日志中查看文件目录)。

3. Nodemailer配置参数错误

代码中secure字段设置为字符串"true",但Nodemailer要求该字段为布尔值,这会导致SMTP连接异常:

  • 修改为布尔值:
    secure: true, // 去掉引号
    

4. Promise未返回导致异步流程中断

sendMail方法创建了Promise但未返回,调用该方法时无法正确处理异步逻辑,在Vercel Serverless函数环境中会导致函数提前结束:

  • 添加return返回Promise:
    sendMail: (data) => {
      // 加上return
      return new Promise((resolve, reject) => {
        // 原代码逻辑
      });
    },
    

5. Gmail OAuth2权限限制

Gmail的OAuth2授权可能限制了生产环境的访问:

  • 登录Google Cloud Console,检查OAuth2客户端的「重定向URI」是否包含Vercel生产域名(若涉及授权流程)。
  • 若使用Gmail App Password,确保账号已开启2FA,且App Password是正确生成的(仅开启2FA后才能创建App Password)。
  • 确认refreshToken有效,可尝试重新生成refreshToken。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 07:50:48