Node.js使用Nodemailer发邮件遇证书错误及无发送结果问题求助
问题描述
我使用Nodemailer编写了如下代码发送邮件:
const from = "info@my_domain.com"; const to = 'some_mail@gmail.com'; const subject = 'my subject'; const html = '<b>Hello world</b>'; const smtpOptions = { "host": "mail.my_domain.com", "port": 587, "secure": false, "auth": { "user": "info@my_domain.com", "pass": "12345679" }, } const transporter = nodemailer.createTransport(smtpOptions); try { const a = await transporter.sendMail({ from, to, subject, html }); } catch (err) { console.log(err); }
运行后出现错误:
Error: self signed certificate at TLSSocket.onConnectSecure
(node:_tls_wrap:1532:34) at TLSSocket.emit (node:events:527:28) at
TLSSocket._finishInit (node:_tls_wrap:946:8) at
TLSWrap.ssl.onhandshakedone (node:_tls_wrap:727:12) { code:
'ESOCKET', command: 'CONN' }
尽管我拥有有效的SSL证书,经查询后我在smtpOptions中添加了如下配置:
tls: { rejectUnauthorized: false }
现在不再报错,但邮件仍未发送。请问该错误产生的原因是什么,如何解决才能正常发送邮件?
原因分析
1. 初始自签名证书错误的根源
你提到有有效SSL证书,但触发self signed certificate错误通常是这几种情况:
- SMTP服务器的证书链不完整,缺少中间证书,导致Node.js无法验证证书合法性
- 服务器使用私有CA颁发的证书,而Node.js默认根证书库不包含该CA
- SMTP服务器主机名与证书上的域名不匹配
2. 关闭证书验证后邮件未发送的原因
rejectUnauthorized: false只是绕过了TLS握手的证书校验,但没解决实际的发送问题,常见原因包括:
- SMTP服务器的端口与
secure参数不匹配(比如587端口需要支持STARTTLS,而你当前配置可能未触发该流程) - 用户名/密码错误,但关闭校验后错误未被正确抛出
- 应用服务器IP被SMTP服务器的防火墙拦截,或邮件被放入服务器发送队列但无反馈
- 代码未打印发送结果,无法确认是否真的触发了发送请求
解决步骤
步骤1:修复证书验证问题(不推荐长期关闭校验)
直接关闭证书验证有安全风险,建议优先修复证书问题:
- 检查SMTP服务器配置,确保安装了完整的证书链(包含根证书和中间证书)
- 如果是私有CA证书,在
tls选项中指定CA证书路径:
const fs = require('fs'); // ... tls: { ca: fs.readFileSync('/path/to/your/ca-cert.pem') }
步骤2:验证SMTP服务器配置匹配度
- 确认端口与
secure参数的对应关系:- 端口587对应
secure: false,但需服务器支持STARTTLS - 端口465对应
secure: true
- 端口587对应
- 用命令行工具测试SMTP连接(比如
swaks),确认服务器是否正常响应:
swaks --to some_mail@gmail.com --from info@my_domain.com --server mail.my_domain.com:587 --auth-user info@my_domain.com --auth-password 12345679 --tls
步骤3:完善代码的日志与错误处理
添加详细日志,明确发送状态:
try { const info = await transporter.sendMail({ from, to, subject, html }); console.log('邮件发送成功,消息ID:', info.messageId); console.log('预览链接:', nodemailer.getTestMessageUrl(info)); } catch (err) { console.error('发送失败详情:', err); console.error('错误代码:', err.code); console.error('服务器响应:', err.response); }
步骤4:检查SMTP服务器的发送限制
- 确认应用服务器IP在SMTP服务器的白名单内
- 检查邮箱账户是否开启了SMTP服务,是否需要使用应用专用密码(比如Gmail开启两步验证后需用应用密码)
- 确认未触发邮件服务器的发送频率限制
内容的提问来源于stack exchange,提问作者Sara Ree
相关产品推荐
相关产品推荐

