推荐答案
在 Go 语言中,html/template 包用于生成安全的 HTML 输出,防止常见的 Web 攻击如跨站脚本攻击(XSS)。它通过自动转义模板中的动态内容来实现这一点。
// www.javascriptcn.com code example
package main
import (
"html/template"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
tmpl := template.Must(template.New("example").Parse(`
<!DOCTYPE html>
<html>
<head>
<title>{{.Title}}</title>
</head>
<body>
<h1>{{.Heading}}</h1>
<p>{{.Content}}</p>
</body>
</html>
`))
data := struct {
Title string
Heading string
Content string
}{
Title: "My Page",
Heading: "Welcome to My Page",
Content: "This is a sample content.",
}
tmpl.Execute(w, data)
})
http.ListenAndServe(":8080", nil)
}本题详细解读
1. 模板定义与解析
在 Go 中,html/template 包允许你定义 HTML 模板,并通过 template.New 和 template.Parse 方法来解析模板。模板中可以包含占位符(如 {{.Title}}),这些占位符将在模板执行时被替换为实际的数据。
// www.javascriptcn.com code example
tmpl := template.Must(template.New("example").Parse(`
<!DOCTYPE html>
<html>
<head>
<title>{{.Title}}</title>
</head>
<body>
<h1>{{.Heading}}</h1>
<p>{{.Content}}</p>
</body>
</html>
`))2. 数据传递与模板执行
模板执行时,可以通过 Execute 方法将数据传递给模板。数据通常是一个结构体或 map,模板中的占位符会根据数据的字段名或键名进行替换。
// www.javascriptcn.com code example
data := struct {
Title string
Heading string
Content string
}{
Title: "My Page",
Heading: "Welcome to My Page",
Content: "This is a sample content.",
}
tmpl.Execute(w, data)3. 自动转义与安全性
html/template 包的一个重要特性是自动转义。它会自动对模板中的动态内容进行 HTML 转义,从而防止 XSS 攻击。例如,如果 Content 字段包含 HTML 标签,这些标签会被转义为文本,而不是被浏览器解析为 HTML。
// www.javascriptcn.com code example
data := struct {
Title string
Heading string
Content string
}{
Title: "My Page",
Heading: "Welcome to My Page",
Content: "<script>alert('XSS');</script>",
}
tmpl.Execute(w, data)在上面的例子中,<script>alert('XSS');</script> 会被转义为 <script>alert('XSS');</script>,从而防止脚本注入。
4. 模板嵌套与复用
html/template 包还支持模板的嵌套与复用。你可以定义多个模板,并通过 {{template "name" .}} 语法在模板中引用其他模板。
// www.javascriptcn.com code example
tmpl := template.Must(template.New("base").Parse(`
<!DOCTYPE html>
<html>
<head>
<title>{{.Title}}</title>
</head>
<body>
{{template "content" .}}
</body>
</html>
`))
tmpl = template.Must(tmpl.New("content").Parse(`
<h1>{{.Heading}}</h1>
<p>{{.Content}}</p>
`))通过这种方式,你可以将复杂的 HTML 页面分解为多个可复用的模板组件。