将 Golang 变量分配给 Javascript

Assign Golang variable to Javascript

目前我遇到了将 Golang 变量分配给 Javascript 变量的相关问题。我使用的是 Golang 模板,所以,我从后端发送了一个 JSON 变量,就像这样:

 var c []models.C
 b, _ := json.Marshal(c)
 err = tpl.ExecuteTemplate(w, "index.gohtml",string(b))

如您所见,我有一个切片,将其转换为 Json,然后将 Json 转换为字符串,并将其发送到模板。然后,在前端我需要将它分配给一个变量,它应该是有效的 JSON,我有这个:

var rowData = {{.}};

但是,我得到 SyntaxError: expected property name, got '{'

所以,我的问题是:我应该如何分配 JSON?

首先,你必须使用html/template instead of text/template,因为前者提供了上下文相关的转义。

其次,模板中的上下文必须清楚表明它是 JavaScript 代码,例如它必须在 HTML <script> 标签内。

查看这个工作示例:

type Point struct {
    Name string
    X, Y int
}

func main() {
    t := template.Must(template.New("").Parse(src))

    p := Point{"Center", 100, 200}
    pj, err := json.Marshal(p)
    if err != nil {
        panic(err)
    }

    if err = t.Execute(os.Stdout, string(pj)); err != nil {
        panic(err)
    }
}

const src = `<script>
var point = {{.}};
alert(point);
</script>`

输出(在 Go Playground 上尝试):

<script>
var point = "{\"Name\":\"Center\",\"X\":100,\"Y\":200}";
alert(point);
</script>

如您所见,point JavaScript 变量包含一个有效的 JSON 文本(一个 JavaScript 对象),已正确转义。

您可以编写自定义模板函数,将您的结构编组到 json。这样您就不必自己在处理程序中编组所有结构。特别是如果您需要在 HTML 模板和 JS 脚本中使用您的结构。

使用 Gin 的示例。

在 main.go 文件中。

    router := gin.New()
    router.SetFuncMap(template.FuncMap{
        "json": func(s interface{}) string {
            jsonBytes, err := json.Marshal(s)
            if err != nil {
                return ""
            }
            return string(jsonBytes)
        },
    })

在你的处理函数中。

type MyStruct struct {
    Foo string `json:"foo"`
}

func Handler(ctx *gin.Context) {
    myStruct := MyStruct{
        Foo: "test",
    }
    
    ctx.HTML(http.StatusOK, "template-file.go.html", gin.H{
        "MyStruct":   myStruct,
    })
}

最后在您的 template.go.html 文件中添加一个脚本标签并在此处定义您的全局变量。稍后您可以在您的 JS 文件中访问它们。

<script type="text/javascript">
    // NB on JSON.parse and json functions!
    let event = JSON.parse({{ json .MyStruct }});
</script>

// Below you can import your JS file as usual.
<script type="text/javascript" src="/assets/js/index.js"></script>