Golang脚本中如何处理HTML模板值

Golang脚本中如何处理HTML模板值 我看到一些HTML模板脚本中使用值的示例,但遇到了错误。例如,在这个网站中给出了以下示例:

{{.Title}}
{{.HTML}}
{{.SafeHTML}}
{{.}}


<a title="{{.Title}}">
<a title="{{.HTML}}">

<a href="{{.HTML}}">
<a href="?q={{.HTML}}">
<a href="{{.Path}}">
<a href="?q={{.Path}}">

<!-- 编码甚至适用于非字符串值! -->
<script>
  var dog = {{.Dog}};
  var map = {{.Map}};
  doWork({{.Title}});
</script>

他可以在脚本中直接使用值{{.}},但在我的IDE中收到这个错误:[js] 需要声明或语句。

是否可以直接在脚本中注入值?如果不能,最好的方法是什么?

谢谢


更多关于Golang脚本中如何处理HTML模板值的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

谢谢

更多关于Golang脚本中如何处理HTML模板值的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你使用的是哪个编辑器?你的代码和我的相同吗?我想在本地尝试复现这个问题,以便在文章中添加说明,避免其他人也感到困惑 😊

我倾向于使用模板目标的常规文件扩展名,后跟模板语言的后缀。

假设我想从模板生成 index.html,我会将模板保存为 index.html.gotpl

对于 Emacs,我有一个了解此约定并适当高亮显示的模式。

[js] 需要声明或语句。

[js] 部分看起来像是你的“智能”IDE试图将其当作嵌入了JavaScript的HTML来检查。请关闭该检查功能,它无法处理模板文件,因为在实际渲染之前,这些文件通常只包含部分或无效的HTML和JavaScript。

我使用VS Code,通过设置 "html.validate.scripts": false 解决了这个问题,这要感谢NobbZ。但存在一个问题:VS Code的格式化工具会使代码产生级联,在浏览器控制台中可以看到这个错误。你可以选择移除HTML文件的HTML格式化功能,或者像我一样将文件扩展名改为 *.gohtml(不过这样也会失去格式化功能)。

祝你好运

在Go的HTML模板中,直接在JavaScript代码中使用模板值是完全可行的,但需要理解模板引擎的上下文感知转义机制。你遇到的IDE错误是因为IDE的JavaScript解析器无法识别Go模板语法,这不会影响实际运行。

问题分析

当你在<script>标签中使用{{.}}时,Go的html/template包会自动进行适当的编码:

  • 字符串值会被JSON编码(包括引号)
  • 数字、布尔值会直接输出
  • 复杂结构会被JSON序列化

解决方案示例

package main

import (
    "html/template"
    "os"
)

type PageData struct {
    Title string
    HTML  string
    Path  string
    Dog   string
    Map   map[string]interface{}
    Count int
    Active bool
}

func main() {
    tmpl := `<!DOCTYPE html>
<html>
<head>
    <title>{{.Title}}</title>
</head>
<body>
    <h1>{{.Title}}</h1>
    
    <!-- 在属性中使用 -->
    <a title="{{.Title}}" href="{{.Path}}">Link</a>
    
    <!-- 在JavaScript中直接使用 -->
    <script>
        var title = {{.Title}};
        var dog = {{.Dog}};
        var count = {{.Count}};
        var active = {{.Active}};
        var mapData = {{.Map}};
        
        console.log(title);    // 输出: "My Page"
        console.log(dog);      // 输出: "Buddy"
        console.log(count);    // 输出: 42
        console.log(active);   // 输出: true
        console.log(mapData);  // 输出: {key: "value"}
        
        function doWork(param) {
            console.log(param);
        }
        
        doWork({{.Title}});
    </script>
</body>
</html>`

    data := PageData{
        Title:  "My Page",
        HTML:   "<div>content</div>",
        Path:   "/home",
        Dog:    "Buddy",
        Count:  42,
        Active: true,
        Map:    map[string]interface{}{"key": "value"},
    }

    t := template.Must(template.New("webpage").Parse(tmpl))
    t.Execute(os.Stdout, data)
}

处理特殊场景

对于需要原始HTML内容的情况,使用template.HTML类型:

type PageData struct {
    Title     string
    SafeHTML  template.HTML  // 不会被转义的HTML
}

data := PageData{
    Title:    "Safe Example",
    SafeHTML: template.HTML("<div class='custom'>Unescaped HTML</div>"),
}

在模板中:

<!-- 安全输出原始HTML -->
<div>{{.SafeHTML}}</div>

<!-- 普通HTML转义 -->
<div>{{.HTML}}</div>

处理复杂数据结构

对于嵌套结构,模板会自动处理JSON序列化:

type User struct {
    Name  string
    Email string
}

type PageData struct {
    User    User
    Tags    []string
    Config  map[string]string
}

data := PageData{
    User:   User{Name: "John", Email: "john@example.com"},
    Tags:   []string{"go", "javascript", "html"},
    Config: map[string]string{"theme": "dark", "lang": "en"},
}

模板中使用:

<script>
    var user = {{.User}};      // {"Name":"John","Email":"john@example.com"}
    var tags = {{.Tags}};      // ["go","javascript","html"]
    var config = {{.Config}};  // {"theme":"dark","lang":"en"}
</script>

Go的HTML模板系统会自动处理XSS防护,在JavaScript上下文中使用适当的JSON编码,确保安全性。IDE的语法错误警告可以忽略,实际执行时模板引擎会正确处理。

回到顶部