0

0

Go html/template:在 HTML 中安全地嵌入 JSON 数据

聖光之護

聖光之護

发布时间:2025-10-27 12:08:01

|

892人浏览过

|

来源于php中文网

原创

Go html/template:在 HTML 中安全地嵌入 JSON 数据

本文探讨了在 go 的 `html/template` 包中,如何在不使用 `

在现代 Web 开发中,我们经常需要将后端 Go 应用程序中的数据结构直接作为 JSON 格式嵌入到 HTML 页面中。这通常用于初始化 JavaScript 库(例如 X-Editable 的 source 属性)、填充 data-* 属性,或在不使用 AJAX 的情况下向前端传递配置信息。html/template 包在处理输出时,默认会进行 HTML 转义以防止跨站脚本攻击 (XSS)。然而,当我们需要输出原始的 JSON 字符串时,这种默认行为会把 " 转换为 "、[ 转换为 [ 等,导致输出不再是有效的 JSON。

本教程将详细介绍两种实现这一目标的方法,并明确它们各自的适用场景和注意事项。

方法一:使用 encoding/json 和 template.HTML 实现真正的 JSON 输出

当目标是生成一个有效的 JSON 字符串,并将其直接嵌入到 HTML 元素(例如作为 data-* 属性的值,或在非

原理说明

  1. JSON 序列化:首先,在 Go 代码中,使用标准库 encoding/json 将 Go 数据结构序列化为 JSON 格式的字节数组或字符串。
  2. 标记为安全 HTML:然后,将生成的 JSON 字符串包装到 template.HTML 类型中。html/template 包在遇到 template.HTML 类型的数据时,会认为这段内容是“安全”的,因此不会对其进行额外的 HTML 转义。

示例代码

package main

import (
    "encoding/json"
    "html/template"
    "log"
    "os"
)

func main() {
    // 定义一个示例数据结构
    type KeyValue struct {
        A, B string
    }

    // 创建一个数据切片
    data := []KeyValue{{"foo", "bar"}, {"bar", "baz"}}

    // 步骤 1: 使用 encoding/json 将 Go 数据结构序列化为 JSON 字符串
    // MarshalIndent 可以生成格式化的 JSON,方便阅读;Marshal 则生成紧凑的 JSON。
    jsonBytes, err := json.MarshalIndent(data, "", " ")
    if err != nil {
        log.Fatalf("JSON 序列化失败: %v", err)
    }
    jsonString := string(jsonBytes)

    // 步骤 2: 将 JSON 字符串包装成 template.HTML 类型
    // 这会告诉 html/template,该字符串是安全的 HTML,不需要进行转义。
    safeJSON := template.HTML(jsonString)

    // 定义模板,直接输出数据
    // 注意:这里的 {{.}} 将直接输出 safeJSON 的内容,不会再进行 HTML 转义。
    tmpl, err := template.New("jsonOutput").Parse(`Hello 
` + "\n") if err != nil { log.Fatal(err) } // 执行模板 log.Println("--- 使用 template.HTML 输出 JSON ---") err = tmpl.Execute(os.Stdout, safeJSON) if err != nil { log.Fatal(err) } // 另一个示例:直接在 body 中输出 tmplBody, err := template.New("jsonBody").Parse(`Hello {{.}}` + "\n") if err != nil { log.Fatal(err) } log.Println("\n--- 直接在 body 中输出 JSON ---") err = tmplBody.Execute(os.Stdout, safeJSON) if err != nil { log.Fatal(err) } }

输出结果

--- 使用 template.HTML 输出 JSON ---
Hello 
--- 直接在 body 中输出 JSON --- Hello [ { "A": "foo", "B": "bar" }, { "A": "bar", "B": "baz" } ]

从输出可以看出,JSON 字符串被完整且正确地嵌入到了 HTML 中,没有经过任何 HTML 转义。这正是我们所期望的,例如,可以用于 data-json 属性或直接作为页面内容。

立即学习前端免费学习笔记(深入)”;

注意事项

  • 安全性:只有当您确定 JSON 字符串的内容是可信的,或者它已经通过 encoding/json 正确序列化(该库本身会处理字符串中的特殊字符转义,例如 " 会被转义为 \"),才应该使用 template.HTML。如果将不可信的原始用户输入直接包装成 template.HTML,将可能导致 XSS 漏洞。
  • 属性值转义:当 JSON 字符串作为 HTML 属性值时(如 data-json='...'),如果 JSON 字符串内部包含单引号 ',可能会导致属性值提前结束。通常情况下,encoding/json 会将内部的 ' 转义为 \u0027," 转义为 \",这在大多数情况下是安全的。如果属性值使用双引号 " 包裹,则 JSON 字符串内部的 " 需被 \" 转义,而 html/template 在 {{.}} 输出到属性上下文时,会进一步处理 " 为 "。为了避免复杂性,推荐在 HTML 属性中使用单引号包裹属性值,并确保 JSON 字符串内部不包含裸露的单引号。json.Marshal 产生的 JSON 字符串通常只包含双引号,所以使用单引号包裹属性值是安全的。

方法二:理解 js 上下文过滤器(JavaScript 字面量转义)

html/template 包提供了一个内置的 js 上下文过滤器,其作用是将值转义,使其可以安全地作为 JavaScript 字面量嵌入到 JavaScript 代码中。然而,它并不会将 Go 数据结构序列化为 JSON 字符串

功能说明

{{js .}} 的主要目的是确保 Go 变量的值在 JavaScript 代码中作为字符串、数字或布尔值字面量使用时不会破坏 JavaScript 语法或引入 XSS 漏洞。例如,如果 Go 变量是一个字符串 alert('XSS'),在 {{js .}} 处理后可能会变成 'alert(\'XSS\')',可以安全地嵌入到 JavaScript 变量赋值中。

PHP的使用技巧集
PHP的使用技巧集

PHP 独特的语法混合了 C、Java、Perl 以及 PHP 自创新的语法。它可以比 CGI或者Perl更快速的执行动态网页。用PHP做出的动态页面与其他的编程语言相比,PHP是将程序嵌入到HTML文档中去执行,执行效率比完全生成HTML标记的CGI要高许多。下面介绍了十个PHP高级应用技巧。 1, 使用 ip2long() 和 long2ip() 函数来把 IP 地址转化成整型存储到数据库里

下载

示例代码及输出分析

package main

import (
    "html/template"
    "log"
    "os"
)

func main() {
    type KeyValue struct {
        A, B string
    }

    data := []KeyValue{{"foo", "bar"}, {"bar", "baz"}}

    // 定义模板,使用 {{js .}}
    // 注意:这里的 {{js .}} 会对 data 进行 JavaScript 字面量转义,但不会进行 JSON 序列化。
    tmplJS, err := template.New("jsOutput").Parse("Hello {{js .}}\n")
    if err != nil {
        log.Fatal(err)
    }

    // 执行模板
    log.Println("--- 使用 {{js .}} 输出 ---")
    err = tmplJS.Execute(os.Stdout, data)
    if err != nil {
        log.Fatal(err)
    }
}

输出结果

--- 使用 {{js .}} 输出 ---
Hello [{foo bar} {bar baz}]

与 JSON 序列化的区别

从输出可以看出,{{js .}} 并没有将 data 切片转换为标准的 JSON 格式,例如 "A": "foo"。它只是输出了 Go 结构体的默认字符串表示,并确保其中的特殊字符(如引号、斜杠等)被正确转义,以便在 JavaScript 环境中安全使用。对于 Go 结构体或切片,其默认的字符串表示通常是 {字段名: 字段值} 的形式。

因此,{{js .}} 不适用于在 HTML 中生成有效的 JSON 字符串。 如果您需要的是符合 JSON 规范的数据,以便被 JavaScript 解析器或库正确识别,请务必使用方法一。

总结与最佳实践

在 Go 的 html/template 中嵌入 JSON 数据时,选择正确的方法至关重要:

  1. 当您需要一个标准的、可被 JavaScript 解析器识别的 JSON 字符串时

    • 最佳实践:始终使用 encoding/json.Marshal(或 MarshalIndent)将 Go 数据结构序列化为 JSON 字符串。
    • 然后,将结果包装成 template.HTML 类型,以防止 html/template 对其进行不必要的 HTML 转义。
    • 示例:template.HTML(string(json.Marshal(myData)))
    • 适用场景:data-* 属性、初始化 JavaScript 库的配置对象、内联 JSON 数据块等。
  2. 当您需要在

    • 适用场景:将一个简单的 Go 字符串或数字直接赋值给 JavaScript 变量。
    • 使用 {{js .}} 上下文过滤器。
    • 重要提示:{{js .}} 不会将 Go 数据结构序列化为 JSON。它只负责转义,使其在 JavaScript 语法中安全。

通过理解这两种方法的区别和适用场景,您可以确保在 Go 应用程序中安全、高效地将数据以 JSON 格式嵌入到 HTML 页面中,同时避免潜在的安全漏洞和数据格式错误。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

418

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

535

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

311

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

77

2025.09.10

ajax教程
ajax教程

php中文网为大家带来ajax教程合集,Ajax是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。php中文网还为大家带来ajax的相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

159

2023.06.14

ajax中文乱码解决方法
ajax中文乱码解决方法

ajax中文乱码解决方法有设置请求头部的字符编码、在服务器端设置响应头部的字符编码和使用encodeURIComponent对中文进行编码。本专题为大家提供ajax中文乱码相关的文章、下载、课程内容,供大家免费下载体验。

160

2023.08.31

ajax传递中文乱码怎么办
ajax传递中文乱码怎么办

ajax传递中文乱码的解决办法:1、设置统一的编码方式;2、服务器端编码;3、客户端解码;4、设置HTTP响应头;5、使用JSON格式。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

117

2023.11.15

ajax网站有哪些
ajax网站有哪些

使用ajax的网站有谷歌、维基百科、脸书、纽约时报、亚马逊、stackoverflow、twitter、hacker news、shopify和basecamp等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

234

2024.09.24

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

31

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.2万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.5万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号