Heroku部署Nodemailer邮件发送失败问题求助
解决Heroku上Nodemailer无法发送邮件的问题
你遇到的H13错误本质是服务器在返回响应前就关闭了连接,大概率是Node.js进程崩溃导致的。结合你本地能正常运行、Heroku部署后失效的情况,我整理了几个针对性的解决方案:
1. 先修复代码里的低级拼写错误
看你贴的路由代码,创建SMTP传输对象时写的是servic: 'gmail'——这里少了个字母e,正确的参数名应该是service: 'gmail'!这个拼写错误会直接导致Nodemailer无法初始化传输服务,本地可能因为调试环境的特性没暴露问题,但在Heroku的生产环境里会直接触发进程崩溃,进而出现H13错误。
修正后的代码片段:
smtpTrans = nodemailer.createTransport({ service: 'gmail', // 修正拼写错误 auth: { user: 'randomemail', pass: 'password' } });
2. 调整Google账户的安全权限
Google现在默认禁止“低安全性应用”访问个人账户,就算你解锁了Captcha也没用,推荐用以下两种方式解决:
- 开启两步验证并生成应用专用密码:如果你的Google账户开了2FA,去账户设置里生成一个「应用专用密码」,用这个密码代替原账户密码填入Nodemailer的配置中。
- 企业账户可开启低安全性应用访问:个人账户已经没有这个选项了,所以优先用应用专用密码方案。
3. 用Heroku环境变量存储敏感信息
绝对不要把邮箱账号和密码硬编码在代码里!既不安全,也可能因为Git提交等操作泄露信息。在Heroku上配置环境变量的步骤:
- 登录Heroku控制台,进入你的应用,找到
Settings->Config Vars - 添加两个变量:
GMAIL_USER(你的邮箱地址)和GMAIL_PASS(应用专用密码或账户密码) - 修改代码里的认证部分:
auth: { user: process.env.GMAIL_USER, pass: process.env.GMAIL_PASS }
4. 完善错误处理逻辑
你当前的错误处理只调用了res.render('contact-failure'),如果渲染过程出错、或者传输对象初始化失败,可能导致没有正确发送响应,进而触发H13。建议添加更健壮的错误捕获:
try { smtpTrans = nodemailer.createTransport({ service: 'gmail', auth: { user: process.env.GMAIL_USER, pass: process.env.GMAIL_PASS } }); mailOpts = { from: `${req.body.name} <${req.body.email}>`, to: process.env.GMAIL_USER, subject: 'New message from contact form at your portfolio page', text: `${req.body.name} (${req.body.email}) says:\n\n${req.body.message}` }; smtpTrans.sendMail(mailOpts, function (error, response) { if (error) { console.error('邮件发送错误:', error); return res.status(500).render('contact-failure'); } else { res.send(response); } }); } catch (err) { console.error('初始化邮件传输错误:', err); res.status(500).render('contact-failure'); }
添加console.error能让你在Heroku日志里看到具体错误信息,方便进一步排查。
5. 查看Heroku详细日志定位问题
除了H13的提示,你可以用Heroku CLI命令查看实时日志:
heroku logs --tail --app desolate-journey-40239
这样能看到进程崩溃的具体原因,比如拼写错误引发的ReferenceError或者SMTP连接失败的详细描述。
建议先从修复拼写错误开始排查,这个是最容易忽略但影响极大的问题,再逐步验证其他设置。
内容的提问来源于stack exchange,提问作者Joshua Wood
相关产品推荐
相关产品推荐

