Go 的 database/sql 包不支持直接扫描 template.HTML 类型,因其无对应 SQL 驱动底层表示;需改用 string 存储原始 HTML,并在模板中显式声明为安全内容,避免自动转义。
go 的 `database/sql` 包不支持直接扫描 `template.html` 类型,因其无对应 sql 驱动底层表示;需改用 `string` 存储原始 html,并在模板中显式声明为安全内容,避免自动转义。
在 Go Web 开发中,常需将富文本(如编辑器生成的 HTML)存入数据库并原样渲染到页面。但直接使用 template.HTML 作为结构体字段并调用 rows.Scan() 会导致该字段被静默忽略——因为 database/sql 的扫描机制仅支持基础类型(如 string, int64, []byte 等),而 template.HTML 是一个带安全标记的字符串别名,本身不可被 SQL 驱动识别或解码。
✅ 正确做法是:
- 数据库字段保持 TEXT 类型,Go 结构体中对应字段声明为 string;
- 在模板中使用 | safeHTML 或 | safe(取决于 Go 版本)显式标记内容为可信 HTML;
- 确保该 HTML 来源可信(如后台管理员输入),防止 XSS 攻击。
修改后的代码示例如下:
type Pages struct {
Name string
Url string
Title string
Description string
H1 string
Hero string
Contents string // ← 改为 string,而非 template.HTML
Sidebar string
Page_list [][]string
}
查询逻辑同步调整(无需改动扫描目标类型):
func db_query_pages(db *sql.DB, err error, page_list [][]string) {
rows, err := db.Query("SELECT name, url, title, description, h1, hero, contents, sidebar FROM pages")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var name, url, title, description, h1, hero, contents, sidebar string
if err := rows.Scan(&name, &url, &title, &description, &h1, &hero, &contents, &sidebar); err != nil {
log.Printf("scan error: %v", err)
continue
}
page := &Pages{
Name: name,
Url: url,
Title: title,
Description: description,
H1: h1,
Hero: hero,
Contents: contents, // ← 直接赋值 string
Sidebar: sidebar,
Page_list: page_list,
}
render_page(page)
}
}
关键:在 HTML 模板中使用 | safeHTML(Go 1.19+ 推荐)或 | safe(旧版):
{{define "content"}}
<h1>{{.H1}}</h1>
<img class="margin-bottom-md block common-border padding-md" src="%7B%7B.Hero%7D%7D">
{{.Contents | safeHTML}} <!-- ✅ 显式声明为安全 HTML -->
{{end}}
⚠️ 注意事项:
- safeHTML 仅在 Go 1.19 及以上版本可用;若使用旧版本,请用 | safe(效果相同,但语义稍弱);
- 切勿对用户直输内容(如评论、表单提交)不经净化就调用 safeHTML,应先使用 bluemonday 或 golang.org/x/net/html 进行白名单过滤;
- template.HTML 仅应在模板渲染前由代码构造(如 template.HTML("OK")),而非从数据库扫描获得;
- 若需复用模板片段(非纯 HTML 字符串),可考虑将模板名存入 DB,再通过 templates.Lookup(name).Execute(...) 动态渲染。
总结:template.HTML 是模板层的安全标记类型,不是数据层传输类型。坚持“存储用 string,渲染前标 safeHTML”,即可兼顾灵活性与安全性。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











