dongye9820
dongye9820
2019-01-18 08:58

在JSON模板中转义值

Using html/template to create JSON output. Code snippet is as follows (playground):

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "html/template"
)

const tpl = `
{
    "key": "{{- .Value -}}" // Replace with js .Value to get another error
}
`

func main() {
    t, err := template.New("").Parse(tpl)
    if err != nil {
        panic(err)
    }
    var buf bytes.Buffer
    err = t.Execute(&buf, struct{
        Value string
    }{"Test\\ > \\ Value"})
    if err != nil {
        panic(err)
    }
    data := make(map[string]string)
    err = json.Unmarshal(buf.Bytes(), &data)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%v
", data)
}

If I try to insert .Value as is - then I get the following error:

panic: invalid character ' ' in string escape code

This is because \\ becomes \ and \ + space is incorrect escaping in JSON. I can fix this by adding js function to template:

const tpl = `
{
    "key": "{{- js .Value -}}"
}
`

In that case it fails with another error:

panic: invalid character 'x' in string escape code

This is because js function converts > sign to \x3c and \x is incorrect escaping in JSON.

Any ideas how to get a universal function that correctly escapes strings for JSON? Is there an alternative way (e.g. an external library) to create JSON templates considering all these difficulties?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • dsyua2828 dsyua2828 2年前

    Option 0

    https://play.golang.org/p/4DMTAfEapbM

    As @Adrian suggested, using text/template, so we do need just one unescape and the end.

    Option 1

    https://play.golang.org/p/oPC1E6s-EwB

    Enscape before excute template, then unenscape twice when you want the string value.

    Option 2

    https://play.golang.org/p/zD-cTO07GZq

    Replace "\\" with "\\\\".

    }{"Test\\ > \\ Value"})
    to
    }{"Test\\\\ > \\\\ Value"})
    

    one more

    "// " comment is not supported in json.

    点赞 评论 复制链接分享

为你推荐