Iris框架本身不封装邮件逻辑,发送邮件需依赖net/smtp或go-mail等库,推荐抽离至service层并配置超时、重试与连接复用,避免在Controller中直接调用阻塞的smtp.SendMail。

smtp.SendMail 是 Go 标准库最直接的发送入口,但 Iris 框架本身不封装邮件逻辑 —— 它只负责 HTTP 路由和上下文管理。真正发邮件,还是得靠 net/smtp 或第三方库(如 gomail、email),Iris 只是把表单参数接进来、传给服务层。
为什么不能直接在 Iris Controller 里调用 smtp.SendMail?
能调,但不推荐。常见错误现象包括:
-
smtp.SendMail是阻塞调用,一次发信可能耗时 1–3 秒,直接放在 HTTP handler 里会拖慢整个请求响应 - 没做连接复用,每次发信都新建 TCP 连接,SMTP 服务器可能限流或拒绝(尤其 Gmail/163 对未认证高频连接敏感)
- 错误处理裸奔:比如
auth failed、535 5.7.8 Username and Password not accepted、421 4.7.0 Try again later等,不包装就直接 panic 或返回 500
正确做法是把发信逻辑抽到 service 层,并加一层轻量包装(比如带重试、超时、日志标记)。
gomail 比 net/smtp 好在哪?
它不是“更高级”,而是把几个硬要自己写的细节默认帮你做了:
立即学习“go语言免费学习笔记(深入)”;
- 自动拼接 MIME 头(
From、To、Subject、Date、MIME-Version)—— 用net/smtp时漏掉\r\n\r\n分隔符是高频 bug - 支持 HTML + 纯文本双版本(
SetBody("text/plain", ...)和SetBody("text/html", ...)) - 内置连接池(
gomail.NewDialer实例可复用),避免每次发信都dial - 附件支持开箱即用(
Attach()),而net/smtp要手动写 multipart boundary
注意:gomail 已归档,官方推荐迁移到 github.com/go-mail/mail(API 几乎一致,只是包名变)。示例中仍用老包名,因兼容性更稳。
Iris 中如何安全传入 SMTP 配置?
别硬编码在 controller 或 service 里。Iris 启动时应从环境变量或配置文件加载,再注入依赖。关键点:
-
SMTP_HOST和SMTP_PORT必须匹配:Gmail 用smtp.gmail.com:587(STARTTLS),163 用smtp.163.com:465(SSL),不能混搭 -
SMTP_USERNAME必须是完整邮箱地址(如user@163.com),不是昵称 -
SMTP_PASSWORD不是登录密码,而是「授权码」或「应用专用密码」—— 163/Gmail 开启 SMTP 服务后单独生成,有效期长且可单独禁用 - 务必设置
Timeout(建议 10s),否则网络卡住时整个 HTTP 请求 hang 死
示例初始化(非 controller 内):
d := gomail.NewDialer(
os.Getenv("SMTP_HOST"),
mustParseInt(os.Getenv("SMTP_PORT")),
os.Getenv("SMTP_USERNAME"),
os.Getenv("SMTP_PASSWORD"),
)
d.Timeout = 10 * time.Second
HTML 邮件模板怎么嵌入 Iris 项目?
别用字符串拼接。Iris 的 context.View 是为 HTML 页面设计的,不适用于邮件内容渲染。正确路径是:
- 把邮件模板放在
templates/email/目录下(与 web view 分开) - 用
html/template单独解析,传入结构体数据(如UserName、VerifyURL) - 注意转义:邮件模板中不要用
{{.Content | safe}},除非你 100% 控制内容来源;HTML 邮件对 XSS 不敏感,但对标签闭合极其敏感(<img>缺/>可能导致整封邮件渲染异常) - 测试时优先用 Thunderbird 或 Outlook Desktop 查看实际渲染效果,Gmail Web 端会 strip 很多 CSS 和 inline style
一个容易被忽略的点:邮件模板里所有 URL 必须是绝对地址(https://example.com/verify?token=xxx),相对路径在邮件客户端里完全无效。


















