html/template 默认转义变量输出以防 xss,需用 safehtml 或 template.html 显式声明可信 html;动态加载需用 fsnotify 重建 template 实例;自定义函数须通过 funcmap 注册且签名受限;嵌套模板需统一解析或手动合并以共享 define。
为什么 html/template 默认会转义所有变量输出
这是 Go 模板最常让人困惑的起点:你传入 "<script>alert(1)</script>",页面上却显示为纯文本。因为 html/template 默认把所有 {{.Var}} 视为 HTML 内容,自动调用 html.EscapeString 防止 XSS。这不是 bug,是安全默认。
如果你确定某段内容是可信的 HTML(比如 CMS 后台编辑器存的富文本),必须显式声明:
- 用
{{.HTMLContent | safeHTML}},前提是.HTMLContent是template.HTML类型 - 不能直接写
{{.HTMLContent | safeHTML}}却传入普通字符串——会报错或静默失败 - 更安全的做法是在 handler 中提前转换:
data.HTMLContent = template.HTML(rawString)
如何让模板支持运行时动态加载和重载(开发期热更新)
Go 的 template.ParseFiles 或 ParseGlob 是编译期绑定路径的,但开发时改完 HTML 要重启服务太慢。关键不是“动态解析字符串”,而是绕过模板缓存、重新 parse。
典型做法是封装一个带文件监听的模板管理器: