在Go语言的Web开发场景中,经常需要在HTML模板中嵌入JSON格式的数据,比如前端初始化配置、接口返回的原始数据等。如果直接使用普通字符串类型输出JSON,Go模板会自动对内容中的特殊字符进行HTML转义,导致JSON格式被破坏,前端无法正常解析。而template.JS类型就是专门用来解决这类问题的安全输出方案。

为什么普通输出会导致JSON异常
Go的html/template包默认会对所有输出的字符串进行HTML转义,目的是防止XSS攻击。比如JSON中的双引号、小于号、大于号等字符都会被转义成对应的HTML实体,例如"会变成",这样原本合法的JSON字符串就会变成无效的格式。
我们通过一个简单的示例来验证这个问题,首先看普通字符串输出的效果:
package main
import (
"html/template"
"net/http"
)
func main() {
tpl := template.Must(template.New("test").Parse(`
<!DOCTYPE html>
<html>
<body>
<script>
var data = {{.jsonData}};
console.log(data);
</script>
</body>
</html>
`))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
jsonStr := `{"name":"test","age":18,"desc":"<p>hello</p>"}`
tpl.Execute(w, map[string]interface{}{
"jsonData": jsonStr,
})
})
http.ListenAndServe(":8080", nil)
}
运行上述代码后,页面中输出的script内容会变成:
var data = {"name":"test","age":18,"desc":"<p>hello</p>"};
这样的内容显然不是合法的JSON,前端执行时会直接报错。
template.JS的作用与原理
template.JS是html/template包中定义的安全类型,它的作用是告诉模板引擎:当前内容是需要嵌入到JavaScript上下文中的可信内容,不需要进行HTML转义,同时模板引擎会对内容进行必要的JS上下文转义,避免JS注入风险。
使用template.JS非常简单,只需要把原始的JSON字符串转换为template.JS类型再传入模板即可。
template.JS实践示例
我们修改上面的示例代码,使用template.JS来输出JSON数据:
package main
import (
"html/template"
"net/http"
)
func main() {
tpl := template.Must(template.New("test").Parse(`
<!DOCTYPE html>
<html>
<body>
<script>
var data = {{.jsonData}};
console.log(data);
console.log(data.name);
console.log(data.desc);
</script>
</body>
</html>
`))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
jsonStr := `{"name":"test","age":18,"desc":"<p>hello</p>"}`
tpl.Execute(w, map[string]interface{}{
// 将JSON字符串转换为template.JS类型
"jsonData": template.JS(jsonStr),
})
})
http.ListenAndServe(":8080", nil)
}
再次运行代码,页面输出的script内容会变成:
var data = {"name":"test","age":18,"desc":"u003cpu003ehellou003c/pu003e"};
可以看到,双引号没有被转义,JSON格式保持完整,同时小于号和大于号被转义成了JS中的unicode编码,这样既保证了JSON的合法性,又避免了恶意脚本注入的风险。前端可以正常解析这个JSON对象,获取对应的字段值。
使用注意事项
- 只有确认内容是可信的JSON数据时才使用
template.JS,不要对用户输入的未校验内容直接使用该类型,否则可能引发XSS攻击。 - 如果JSON数据中包含换行符等特殊字符,需要确保JSON本身是合法的,否则即使使用
template.JS也会导致JS语法错误。 - 除了
template.JS,html/template还提供了template.HTML、template.CSS等安全类型,分别对应不同上下文的可信内容输出,使用时需要匹配对应的上下文场景。
不同输出方式对比
我们可以通过表格更直观地看到不同输出方式的差异:
| 输出类型 | 是否HTML转义 | 是否JS上下文转义 | 适用场景 |
|---|---|---|---|
| 普通字符串 | 是 | 否 | 普通HTML文本内容输出 |
| template.JS | 否 | 是 | JavaScript上下文中的可信内容输出 |
| template.HTML | 否 | 否 | HTML上下文中的可信内容输出 |
常见问题解答
如果JSON中包含用户输入的内容怎么办
如果JSON中包含用户输入的内容,需要先对用户输入的内容进行校验和转义,确保JSON本身是合法的,并且没有恶意脚本内容,再转换为template.JS类型输出。可以使用encoding/json包来序列化包含用户输入的数据,避免手动拼接JSON导致的格式错误和安全问题。
template.JS会影响JSON的性能吗
template.JS本身只是类型转换,不会带来明显的性能损耗,它的处理逻辑只是告诉模板引擎使用对应的转义规则,不会额外处理数据内容,因此可以放心使用。
Go模板template.JS原始JSON输出安全输出HTML转义修改时间:2026-07-05 05:18:24