Go语言使用net/smtp发送电子邮件完整示例
利用Go标准库net/smtp实现电子邮件发送功能。文章详细解析了SendMail和PlainAuth函数的用法,提供了包含服务器配置、认证处理、多收件人循环及HTML内容拼接的完整代码示例,并针对网易邮箱常见的反垃圾邮件拦截错误给出了符合RFC规范的解决方案。
核心函数原理
第1步:理解底层机制
net/smtp包提供了基于简单邮件传输协议(SMTP)的低级接口,具体遵循RFC 5321标准。它主要包含两个关键函数:
- PlainAuth:创建身份验证机制。使用指定的用户名和密码,通过TLS连接到指定主机。参数中
identity通常设为空字符串以直接使用用户名作为身份标识。 - SendMail:执行发送动作。连接服务器,开启TLS(若支持),进行身份认证,并以指定发件人地址将消息发送至目标列表。
注意:SendMail属于低级机制,不直接支持DKIM签名或MIME附件构造,高级邮件功能需自行组装消息体。
功能实现步骤
第2步:定义数据结构
为了清晰管理配置与内容,建议定义结构体。配置信息包含SMTP服务器地址、端口及授权密码;邮件内容包含发件人、主题、正文及多个收件人地址。
type configInfo struct {
smtpAddr string
smtpPort string
secret string // 通常为授权码而非登录密码
}
type emailContent struct {
fromAddr string
contentType string // "html" 或 "plain"
theme string
message string
toAddr []string
}第3步:组装符合RFC 822的消息体
大多数SMTP报错(如网易邮箱的SPM拦截)源于消息头格式不规范。必须严格遵循“头部 + 空行 + 正文”且行尾为CRLF(\r\n)的格式。对于HTML邮件,需在头部声明正确的Content-Type。
func sendEmail(c *configInfo, e *emailContent) error {
// 1. 拼接服务器地址
smtpAddr := c.smtpAddr + ":" + c.smtpPort
// 2. 创建认证对象
auth := smtp.PlainAuth("", e.fromAddr, c.secret, c.smtpAddr)
// 3. 确定内容类型头
var contentTypeHeader string
if e.contentType == "html" {
contentTypeHeader = "Content-Type: text/html; charset=UTF-8"
} else {
contentTypeHeader = "Content-Type: text/plain; charset=UTF-8"
}
// 4. 循环发送给每个收件人
for _, to := range e.toAddr {
// 严格按照 RFC 822 格式构建 msg
msg := "To: " + to + "\r\n" +
"From: " + e.fromAddr + "\r\n" +
"Subject: " + e.theme + "\r\n" +
contentTypeHeader + "\r\n" +
"\r\n" +
e.message // 此处可直接填入HTML片段
err := smtp.SendMail(smtpAddr, auth, e.fromAddr, []string{to}, []byte(msg))
if err != nil {
return err
}
}
return nil
}第4步:调用示例与防拦截优化
在实际使用中,需注意以下细节以避免被标记为垃圾邮件:
- 标题与发件人一致性:确保邮件主题和发件人地址合理,避免使用纯测试占位符。
- CRLF规范:Go字符串中的
\r\n会自动转为CRLF,但切勿混用\n。 - 多收件人处理:虽然
SendMail支持一次性发送多个to参数,但在某些严格的服务器策略下,逐个发送或保持头部清晰更佳。
以下是完整的初始化与调用流程:
func main() {
config := configInfo{
smtpAddr: "smtp.yeah.net",
smtpPort: "25",
secret: "your_authorization_code",
}
content := emailContent{
fromAddr: "sender@yeah.net",
toAddr: []string{"recipient@qq.com", "other@126.com"},
contentType: "html",
theme: "测试邮件主题",
message: "<h1>Hello</h1><p>这是一封通过Go发送的HTML邮件</p>",
}
if err := sendEmail(&config, &content); err != nil {
log.Fatal(err)
}
fmt.Println("发送成功")
}常见问题排错
在使用网易系(163/Yeah)邮箱时,常遇到如下错误:
554 DT:SPM ... please see http://mail.163.com/help/help_spam_16.htm
这通常意味着邮件未通过反垃圾系统检查。主要原因包括:
- 头部缺失或不规范:缺少标准的From、To或Subject字段,或未正确换行。
- 内容被识别为垃圾特征:包含大量链接、敏感词或纯文本形式可疑。
- IP信誉问题:本地服务器IP可能被列入黑名单。
解决方法:确保严格按照上述代码结构拼接头部,并在Message-ID等可选头部中添加唯一标识,同时保证From地址与实际发送账户一致。
总结
Go语言通过net/smtp提供了简洁高效的邮件发送能力。关键在于手动构建符合RFC 822标准且带有正确CRLF结尾的消息体,并妥善处理身份验证。对于需要复杂MIME附件的场景,可结合mime/multipart包进行进一步扩展。以上就是Go语言实现SMTP邮件发送的详细内容,更多关于Go网络编程的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













