必须用html/template渲染html,因其自动上下文感知转义(如html、url、js编码)防止xss;text/template无转义,仅适用于纯文本场景;错误使用会导致脚本执行或模板静默失效。

用 html/template 而不是 text/template 渲染 HTML 字符串
只要输出目标是 HTML(哪怕只是片段),必须用 html/template。它会在渲染时自动对 、<code>>、&、"、' 做上下文感知转义,比如在 href="" 中会 URL 编码,在 script 标签内会 JavaScript 编码——这是防 XSS 的第一道硬防线。
常见错误现象:
- 用
text/template渲染用户昵称"<script>alert(1)</script>",结果直接执行脚本 - 模板里写
@#@#@#@#@#@#@#@#@#@0,而.URL是javascript:alert(1),html/template会把它转成javascript%3Aalert%281%29,从而失效
使用场景:生成邮件正文、管理后台页面、API 返回的 HTML 片段等所有含用户数据的 HTML 输出。
多源数据组合:用 map[string]interface{} 或结构体嵌套,别拼字符串
动态组合多个来源的数据(如配置项 + 用户信息 + 时间戳 + 权限状态),最安全的方式是统一收口到一个顶层数据结构,再传给 Execute。不要用 fmt.Sprintf 或字符串拼接把不同来源的值先“组装”成中间字符串——那等于主动绕过模板的转义机制。
示例中易踩的坑:
- 错误:
userPart := fmt.Sprintf(`<span>%s</span>`, user.Name),再把userPart当作字符串塞进模板 → XSS 漏洞已埋下 - 正确:把
user、config、now全部作为字段放进一个 struct 或 map,例如data := map[string]interface{}{"User": user, "Config": cfg, "Now": time.Now()} - 结构体字段必须首字母大写(可导出),否则模板里读不到
性能影响:一次 Execute 调用比多次字符串拼接 + 多次 Execute 更快,且内存分配更可控。
自定义函数注入:通过 FuncMap 扩展能力,不碰解析器
需要日期格式化、环境判断、权限检查等逻辑?别重写模板引擎,直接往 template.FuncMap 里加函数。标准库的解析器已经足够健壮,自己实现只会引入作用域泄漏、空指针 panic、HTML 上下文错位等隐患。
实操要点:
- 所有函数必须返回
string、int、bool等模板能识别的类型;避免返回error,若需报错应在函数内处理并返回默认值 - 函数签名要明确,例如:
"envEq": func(a, b string) bool { return a == b },不能接受interface{}后再反射判断 - 禁止在函数里操作
http.ResponseWriter或修改全局状态;模板函数应是纯数据转换 - 注册方式:
t := template.New("main").Funcs(myFuncMap)
典型误用:在自定义函数里调用 os.ReadFile 读取模板文件并递归 Parse —— 这属于模板继承范畴,该用 {{template "name" .}} + ParseFiles 解决。
预编译与复用:避免每次请求都 Parse,用 Clone 隔离不同环境
生产环境下,模板字符串或文件内容基本不变。每次 HTTP 请求都调用 template.Parse 是严重性能浪费,且可能因并发解析引发 panic。正确做法是在启动时一次性 Parse,之后复用模板实例。
复杂点在于多环境(dev/staging/prod)需注入不同函数或配置:
- 用
t.Clone()创建副本,再调用.Funcs()注入环境专属函数,不影响主模板 - Go 1.22+ 可配合
template.WithContext把context.Context透传进自定义函数,用于超时控制或 trace ID 注入 - 若模板来自用户上传或 API 动态下发,务必加白名单校验(只允许特定函数名和语法结构),并设置解析超时(用
template.Must包裹时尤其注意 panic 传播)
最容易被忽略的是:当模板内容来自不可信渠道(如 CMS 后台编辑器),即使用了 html/template,也要限制其可调用的函数集——默认 FuncMap 可能包含危险函数(如 printf 配合恶意格式化字符串可触发内存越界),应显式构造最小可用集合。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











