英文:
Escape HTML in array field in struct
问题
当你在结构体的数组字段中进行HTML转义时,你可以使用html/template
包提供的html
函数来实现。
对于单个展示页面,你可以使用以下代码:
show.go:
err := ShowTmpl.ExecuteTemplate(w, "show.html", struct {
Title string
SafeBody template.HTML
}{
t.Title,
template.HTML(t.BodyHTML),
})
对于索引页面:
index.go:
type as struct {
Articles []*Article
}
var a as
// 一些代码来给a.Articles赋值
err := IndexTmpl.ExecuteTemplate(w, "index.html", a)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
index.html:
{{with .Articles}}
{{range .}}
<a href="/">{{.Title}}</a>
{{.BodyHTML | html}} <!-- 这里不起作用 -->
{{end}}
{{end}}
当你在结构体字段上进行迭代时,可以使用html
函数来转义HTML内容,例如{{.BodyHTML | html}}
。这将确保HTML标签被正确转义,以防止XSS攻击。
英文:
How do I escape HTML when I have an array field in a struct?
For a single show page, this code works:
show.go:
err := ShowTmpl.ExecuteTemplate(w, "show.html", struct {
Title string
SafeBody template.HTML
}{
t.Title,
template.HTML(t.BodyHTML),
})
For an index page:
index.go
type as struct {
Articles []*Article
}
var a as
// some code to give a.Articles its values
err := IndexTmpl.ExecuteTemplate(w, "index.html", a)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
index.html:
{{with .Articles}}
{{range .}}
<a href="/">{{.Title}}</a>
{{.BodyHTML | html}} // Doesn't work
{{end}}
{{end}}
How do I escape HTML when I'm ranging over a struct field?
答案1
得分: 2
你可以通过以下几种方式实现这个目标:
1. 使用自定义函数
你可以使用自定义函数。Template.Funcs()
方法允许你注册任何自定义函数,这些函数可以从模板中调用。
创建一个简单的函数,将 string
转换为 template.HTML
,代码如下:
func ToHtml(s string) template.HTML {
return template.HTML(s)
}
你可以像这样注册它:
t := template.Must(template.New("index.html").
Funcs(map[string]interface{}{"ToHtml": ToHtml}).Parse(indexHtml))
这里只是为了演示目的,indexHtml
是你的模板的 string
:
const indexHtml = `{{with .}}
{{range .}}
<a href="/">{{.Title}}</a>
{{ToHtml .BodyHTML}}
{{end}}
{{end}}
`
你可以在模板中这样引用和调用它:
{{ToHtml .BodyHTML}}
使用参数调用这个模板:
a := []struct {
Title string
BodyHTML string
}{{"I'm the title", "I'm some <b>HTML</b> code!"}}
err := t.ExecuteTemplate(os.Stdout, "index.html", a)
这是在 Go Playground 上的完整示例。
2. 修改 Article
结构体
如果可以的话,更简单的方法是将 Article.BodyHTML
的类型更改为 template.HTML
,这样它将被渲染为未转义的 HTML。这也会使意图清晰(它应该/包含安全的 HTML,并将以未转义的形式呈现)。
3. 在 Article
中添加一个方法
你还可以在 Article
类型中添加一个方法,该方法将 BodyHTML
字段作为 template.HTML
返回(与建议 #1 中的自定义函数基本相同):
func (a *Article) SafeBody() template.HTML {
return template.HTML(a.BodyHTML)
}
有了这个方法,你可以在模板中直接调用它:
{{range .}}
<a href="/">{{.Title}}</a>
{{.SafeBody}}
{{end}}
在 Go Playground 上尝试这个变体。
英文:
You can achieve this in several ways:
1. With a custom function
You can use a custom function. The Template.Funcs()
method allows you to register any custom functions which can be invoked from templates.
Create a simple function which converts a string
to template.HTML
like this:
func ToHtml(s string) template.HTML {
return template.HTML(s)
}
You can register it like this:
t := template.Must(template.New("index.html").
Funcs(map[string]interface{}{"ToHtml": ToHtml}).Parse(indexHtml))
Where just for demonstration purposes indexHtml
is a string
of your template:
const indexHtml = `{{with .}}
{{range .}}
<a href="/">{{.Title}}</a>
{{ToHtml .BodyHTML}}
{{end}}
{{end}}
`
And you can refer to it and call it from the template like this:
{{ToHtml .BodyHTML}}
Calling this template with a parameter:
a := []struct {
Title string
BodyHTML string
}{{"I'm the title", "I'm some <b>HTML</b> code!"}}
err := t.ExecuteTemplate(os.Stdout, "index.html", a)
Here's the complete, working example on the Go Playground.
2. Modifying Article
If you can, it would be easier to just change the type of Article.BodyHTML
to template.HTML
and then it would be rendered unescaped without further ado. This would also make the intent clear (that it should/does contain safe HTML which will be rendered unescaped).
3. Adding a method to Article
You can also add a method to the Article
type which would return its BodyHTML
field as a template.HTML
(pretty much what the custom function does in proposition #1):
func (a *Article) SafeBody() template.HTML {
return template.HTML(a.BodyHTML)
}
Having this method you can simply call it from the template:
{{range .}}
<a href="/">{{.Title}}</a>
{{.SafeBody}}
{{end}}
Try this variant on the Go Playground.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论