必须用 html/template 渲染 HTML 邮件,设 Content-Type: text/html,数据字段首字母大写,HTML 内容需用 template.HTML 包装,禁用 JS 和外链 CSS,优先用表格布局。

怎么用 html/template 渲染带变量的邮件正文
直接能用,但得注意模板里不能有未转义的用户输入,否则 HTML 注入风险极高。默认 html/template 会自动转义,这点比 text/template 安全,但代价是如果你真想插入合法 HTML(比如邮件里的 <strong> 标签),得显式调用 template.HTML 包装。
- 用
html/template.ParseFiles()或ParseGlob()加载 .html 模板文件,路径别写错,比如"templates/email.html" - 执行时传入结构体或 map,字段名首字母必须大写(Go 导出规则),否则模板里取不到
- 如果模板里要渲染一段已构造好的 HTML 字符串(如富文本编辑器内容),得在数据层提前转成
template.HTML类型,不能在模板里用{{.Content | safeHTML}}——html/template不提供这个 func - 别在模板里写 JS 或内联样式,多数邮件客户端(Outlook、Apple Mail)会过滤或不支持
为什么发出去的邮件显示的是源码而不是渲染结果
常见原因是 Content-Type 没设对,或者用了 text/template 却当成 HTML 发。
- SMTP 发送时,必须在邮件头明确设置
Content-Type: text/html; charset=utf-8,光模板渲染对没用 - 用
gomail库的话,调m.SetBody("text/html", ...);用net/smtp手写则要自己拼 header,漏掉\r\n\r\n分隔符会导致整个 body 被当 header 解析 - 如果用
text/template渲染 HTML 字符串,所有<>全被转义成,打开就是一堆实体字符——必须换 <code>html/template
html/template 和 text/template 在邮件场景怎么选
只有一种合理选择:无条件用 html/template,除非你确定邮件纯文本且永远不加链接、加粗、换行。
-
html/template默认转义,防 XSS;text/template不转义,容易把用户输入的<script>直接塞进邮件(虽然客户端大概率不执行,但语义污染严重) - 二者 API 几乎一致,替换成本极低:改 import、改
template.New()的包路径,再检查下数据类型是否满足导出要求 - 性能差异可忽略,渲染耗时主要在 IO(读模板文件、发网络请求),不在模板引擎本身
- 别为了“兼容老代码”硬用
text/template+ 手动strings.ReplaceAll去还原标签——这等于自己造漏洞
本地预览 HTML 邮件效果很奇怪怎么办
不是你的模板问题,是浏览器和邮件客户端渲染逻辑根本不同。不要用 Chrome 直接打开 .html 文件看效果。
立即学习“go语言免费学习笔记(深入)”;
- 用
mailcatcher或smtp4dev搭个本地 SMTP 服务,真实走一遍发送流程,再用网页端查看渲染结果 - 真正发测试邮件前,先用
fmt.Println(string(buf.Bytes()))打印完整原始邮件内容,确认Content-Type、boundary、HTML body 都在正确位置 - 避免 CSS 外链,邮件中只用内联 style;class 名别起太花哨,有些客户端(特别是 Outlook)会删掉不认识的 class 属性
- 表格布局仍是最稳妥的方案,Flex/Grid 基本别指望



















