Nodemailer如何获取收件人地址错误的发送失败响应?
Nodemailer收件人地址错误无法即时获取失败响应的解决方法
为什么收件人错误却显示发送成功?
这是SMTP协议的特性:多数邮件服务器(比如你用的Office365 SMTP)不会在发送阶段直接验证收件人地址是否真实存在,只会先接收邮件并返回250 OK的成功响应,之后如果发现收件人不存在,才会通过**退信(Bounce)**的方式通知发件人。所以sendMail的回调里不会直接捕获到这类错误。
如何获取收件人错误的响应?
1. 检查info对象的rejected数组
如果收件人地址格式完全无效(比如包含非法字符),或者被SMTP服务器直接拒绝,该地址会出现在info.rejected数组中。但这种情况只覆盖极少部分场景,大多数真实存在但无对应邮箱的地址不会被即时拒绝。
修改你的回调代码,增加对rejected的判断:
transport.sendMail(mailOptions, (err, info) => { if (err) { return console.log(err); } console.log('已接受的收件人:', info.accepted); if (info.rejected.length > 0) { console.log('被拒绝的收件人:', info.rejected); // 这里处理被即时拒绝的地址 } transport.close(); });
2. 监听发件邮箱的退信(Bounce)
这是处理收件人不存在这类问题的通用方案:
- 给你的发件邮箱配置IMAP/POP3服务,用代码监听新邮件
- 识别退信邮件(通常主题包含"Undelivered Mail Returned to Sender"或类似关键词,邮件内容包含失败原因和收件人地址)
- 解析退信内容,提取失败的收件人信息
示例代码(用Nodemailer的IMAP客户端):
const Imap = require('imap'); const { simpleParser } = require('mailparser'); const imapConfig = { user: 'sender@mydomain.com', password: '你的邮箱密码', host: 'outlook.office365.com', // Office365的IMAP服务器 port: 993, tls: true }; const imap = new Imap(imapConfig); function openInbox(cb) { imap.openBox('INBOX', false, cb); } imap.once('ready', function() { openInbox(function(err, box) { if (err) throw err; // 监听新邮件 imap.on('mail', function() { const fetch = imap.seq.fetch('1:*', { bodies: '' }); fetch.on('message', function(msg, seqno) { msg.on('body', function(stream, info) { simpleParser(stream, (err, parsed) => { if (err) throw err; // 判断是否是退信 if (parsed.subject.includes('Undelivered') || parsed.text.includes('Delivery failed')) { // 解析失败的收件人地址,示例逻辑需根据实际退信格式调整 const failedRecipientMatch = parsed.text.match(/to: (.*)/); if (failedRecipientMatch) { console.log('投递失败的收件人:', failedRecipientMatch[1]); console.log('失败原因:', parsed.text); } } }); }); }); }); }); }); imap.once('error', function(err) { console.log(err); }); imap.once('end', function() { console.log('IMAP连接关闭'); }); imap.connect();
注意:不同邮件服务商的退信格式差异较大,你需要根据实际收到的退信内容调整解析逻辑。
内容的提问来源于stack exchange,提问作者Chris He
相关产品推荐
相关产品推荐

