在开发web的时候,几乎必然会用到标准库 html/template。在默认的情况下,渲染模板时,为了安全等原因会将字符串中的特殊符号进行转义。比如:html代码。
下面定义一个简单的模板。
<body>
{{.Content}}
</body>
默认情况下,对模板进行渲染是这样的。
dataShow := struct {
Content string
}{}
dataShow.Content = "<p> Love U,CoFox.Com </p>"
files, err := template.ParseFiles("./cofox.html")
if err != nil {
...
}
err1 := files.Execute(writer, dataShow)
正常情况下会显示成这样。
<body>
<p> Love U,CoFox.Com </p>
</body>
为了避免这种情况,通常在go代码中,把字段 Content 的类型固定的设置为 template.HTML。
dataShow := struct {
Content template.HTML
}{}
这种做法,实现简单,却非常不灵活。
我们更希望把前端的表现形式交由前端代码来控制。
为了更加灵活,我们可以采用:
注册自定义转义处理函
可以使用模版的 Funcs() 方法注册自定义函数。
为了实现避免转义HTML文本的效果,我们先要定义一个函数用于处理将字符串转为template.HTML类型。例如我们定一个名为 CoFoxTemplateFieldUseHTML 的函数:
// CoFox不转义HTML(直接使用HTML代码)
func CoFoxTemplateFieldUseHTML(s string) template.HTML {
return template.HTML(s)
}
然后,我们需要使用 Funcs() 将其注册到模版中。需要注意,注册自定义函数需要在调用 Parse() 或 ParseFiles() 前进行。在注册时我们需要定义一个函数标识符,并在模版文本中使用。在下面例子中我们使用了名为 showHTML 的函数标识符。
dataShow := struct {
Content string
}{}
dataShow.Content = "<p> Love U,CoFox.Com </p>"
files, err := template.New("cofox").Funcs(template.FuncMap{"showHTML": CoFoxTemplateFieldUseHTML}).ParseFiles("./cofox.html")
if err != nil {
...
}
err1 := files.Execute(writer, dataShow)
模板HTML
<!doctype html>
<html lang="en">
<body>
{{showHTML .Content }}
<br>
{{.Content }}
</body>
</html>
我们将得到这样的结果
<p> Love U,CoFox.Com </p>
<br>
<p> Love U,CoFox.Com </p>
注意:
html/template同样也提供了例如template.JS、template.CSS等类型,用于Javascript或是CSS的处理。
html/template 包默认进行转义很大程度上避免了一些安全性的问题,例如潜在的XSS攻击等。在实际使用中,进行“不转义”处理后将存在安全性方面的风险,对于风险较高的使用场合需要另外考虑这方面的处理方案。