贝利信息

如何在Golang中进行模板渲染_Golang text/template与html/template方法

日期:2026-01-26 00:00 / 作者:P粉602998670
根本区别在于自动转义行为:html/template默认对插值做HTML实体转义,text/template完全不转义;渲染HTML必须用html/template,纯文本场景用text/template。

text/template 和 html/template 的核心区别在哪

根本区别不在语法,而在自动转义行为:html/template 默认对所有 .Value 插值做 HTML 实体转义(如 zuojiankuohaophpcn),text/template 完全不转义。选错会导致 XSS 漏洞或页面显示乱码。

如何安全地在 html/template 中插入原始 HTML

直接写 {{.HTMLContent}} 会被转义成一堆 zuojiankuohaophpcndivyoujiankuohaophpcn —— 这不是 bug,是默认防护。要绕过转义,必须显式声明该值“已可信”:

func main() {
	tmpl := template.Must(template.New("").Parse(`{{.SafeHTML}}`))
	data := struct{ SafeHTML template.HTML }{
		SafeHTML: template.HTML(`hello`),
	}
	tmpl.Execute(os.Stdout, data)
}

模板中调用函数和方法要注意什么

两者都支持自定义函数和接收者方法,但函数注册逻辑一致,而方法调用受接收者类型限制:

func sayHi(name string) string { return "Hi, " + name }
tmpl := template.Must(template.New("t").Funcs(template.FuncMap{"hi": sayHi}))
tmpl.Parse(`{{hi .Name}}`) // ✅ 正确

常见 panic 错误:template: xxx: unexpected “.” in operand

多因模板语法写错,比如漏掉空格、括号不匹配,或在 {{if}} 条件里用了非法表达式:

最易被忽略的是:同一个 *template.Template 实例不能并发调用 Execute,必须为每次请求克隆一份(tmpl.Clone())或创建新实例——否则可能 panic 或输出错乱。