生产环境应使用gomail.v2而非net/smtp手拼邮件体,因其自动处理mime、utf-8编码、中文主题、附件名、多部分结构等rfc规范细节,避免gmail拒收或outlook乱码。

别用 net/smtp 手拼邮件体——除非你真在学协议或写一次性调试脚本。生产环境发邮件,直接上 gomail.v2,它把 MIME、编码、多部分结构、附件、中文头这些坑全包了。
为什么不用 net/smtp 直接发
net/smtp 只管 TCP 连接和 SMTP 协议交互,不处理邮件格式。你要自己写 RFC 5322 兼容的字节流:头字段顺序不能错、\r\n 换行不能少、头与正文之间必须两个 \r\n、Subject 含中文得 Base64 编码(如 =?UTF-8?B?5byg5LiJ?=)、Content-Type 必须带 charset=utf-8 且不能加引号。漏一项,Gmail 就拒收,Outlook 就显示乱码。
常见翻车点:
-
530 5.7.0 Sender address rejected:发件人地址(From头)和认证账号不一致 - HTML 邮件显示源码:没设
Content-Type: text/html; charset=utf-8,或根本没构造 multipart 结构 - 附件名是
noname:中文文件名没用 encoded-word 编码(如=?UTF-8?B?5byg5LiJLmpwZw==?=)
gomail.v2 发纯文本和 HTML 邮件
安装:go get gopkg.in/gomail.v2(v3 已废弃,别踩坑)。
发 HTML 邮件只需改一个参数:
m.SetBody("text/html", "<h1>你好</h1><p>这是 HTML</p>")
要同时支持纯文本 + HTML(让客户端自动选),用 AddAlternative:
m.SetBody("text/plain", "这是纯文本版本")
m.AddAlternative("text/html", "<h1>这是 HTML 版本</h1>")
关键细节:
-
SetHeader("From", "a@example.com")的值必须和 SMTP 认证账号完全一致 - 收件人用
SetHeader("To", "a@x.com", "b@y.com"),不是字符串拼接 - 主题含中文?
SetHeader("Subject", "测试邮件")直接传就行,gomail自动编码
Gmail / QQ / 163 邮箱配置差异
硬套一个配置肯定连不上。核心区别在三处:端口、加密方式、密码类型。
-
Gmail:必须开两步验证 → 生成 App Password(16 位),用
smtp.gmail.com:587+ STARTTLS -
QQ 邮箱:设置里开 SMTP → 获取授权码,用
smtp.qq.com:587+ STARTTLS -
163/126:开 SMTP 服务 → 设置独立授权码,端口常用
465(需 SSL)或25(不推荐)
用 gomail.NewDialer 时,第四个参数(密码)填的就是这个授权码,不是登录密码。
超时、重试、错误分类不能靠默认
gomail 默认不设超时,网络卡住就 goroutine 挂死;也不自动重试,535 认证失败再试十次也没用。
实操建议:
- 用
context.WithTimeout包裹发送:10 秒内没响应就放弃 - 重试只针对连接失败(如
dial tcp: i/o timeout),不重试 5xx SMTP 错误码 - 错误信息里解析标准码:比如
535 5.7.8是密码错,554是内容被拒,该告警就告警,不该重试就别 retry
真正容易被忽略的是:SMTP 连接成功 ≠ 邮件送达。Message-ID 不保存、退信不监听、失败不落库,等于没做监控。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











