如何在 Go 中通过 SMTP 发送邮件并自定义发件人姓名

16次阅读

如何在 Go 中通过 SMTP 发送邮件并自定义发件人姓名

go 中使用标准库 `net/smtp` 发送邮件时,仅靠 `client.mail()` 传入带名称的邮箱会导致 501 错误;正确做法是将“显示名称 + 邮箱”格式写入邮件正文头部的 `from` 字段,而 `client.mail()` 参数必须为纯邮箱地址。

go 标准库 net/smtp 的 Client.mail(from String) 方法仅接受 RFC 5321 兼容的纯邮箱地址(如 [email protected],不支持 “Name ” 这类带显示名的格式——否则 SMTP 服务器会拒绝并返回 501 5.1.7 Invalid address。

真正控制收件端显示名称的,是邮件内容头部(MIME header)中的 From: 字段。该字段遵循 RFC 5322,允许使用带引号的显示名语法:

From: Sandy Sender <[email protected]>

✅ 正确实现步骤如下:

  1. Client.Mail() 传纯邮箱地址(用于 SMTP 协议层身份验证与投递路由);
  2. 在构造邮件正文时,在头部显式设置 From: 行,格式为 “显示名 “;
  3. 确保整个邮件符合 MIME 格式(含空行分隔头与体、正确编码等)。

✅ 手动构造示例(标准库)

package main  import (     "fmt"     "net/smtp"     "strings" )  func main() {     auth := smtp.PlainAuth("", "user@example.com", "app-password", "smtp.example.com")      to := []string{"[email protected]"}     from := "[email protected]" // ← 仅邮箱!用于 Mail()     fromHeader := "Sandy Sender <" + from + ">" // ← 带名格式!用于 From: 头部      msg := fmt.Sprintf(         "From: %srn"+             "To: %srn"+             "Subject: Hello from Go!rn"+             "MIME-Version: 1.0rn"+             "Content-Type: text/plain; charset=utf-8rn"+             "rn"+             "This is the body of the message.",         fromHeader, strings.Join(to, ", "),     )      err := smtp.SendMail(         "smtp.example.com:587",         auth,         from,     // ← 关键:纯邮箱         to,         []byte(msg),     )     if err != nil {         panic(err)     } }

✅ 推荐方案:使用 gomail(更安全、更简洁)

手动拼接邮件头易出错(如编码缺失、换行符不规范)。推荐使用成熟封装gomail(v2),它自动处理 RFC 合规性、UTF-8 编码、MIME 分隔等细节:

package main  import (     "gopkg.in/gomail.v2" )  func main() {     m := gomail.NewMessage()     m.SetAddressHeader("From", "[email protected]", "Sandy Sender")     m.SetAddressHeader("To", "[email protected]")     m.SetHeader("Subject", "Hello!")     m.SetBody("text/plain", "This is the body of the message.")      d := gomail.NewPlainDialer("smtp.example.com", 587, "user@example.com", "app-password")      if err := d.DialAndSend(m); err != nil {         panic(err)     } }

⚠️ 注意事项: 显示名(如 “Sandy Sender”)若含非 ASCII 字符(如中文),gomail 会自动进行 B 类型 MIME 编码(如 =?UTF-8?B?5byg5LiJ?=),而手动拼接需自行调用 mime.BEncoding.Encode(); SMTP 认证凭据建议使用应用专用密码(如 Gmail App Password),避免主密码泄露; 生产环境务必启用 TLS(gomail.NewDialer 支持 TLSConfig),禁用明文传输。

通过分离「协议层发件地址」与「展示层发件人信息」,即可优雅实现专业邮件署名效果。

text=ZqhQzanResources