golang - 显示字符,而不是ascii。喜欢'&',而非'\ 0026'

时间:2014-07-09 14:36:21

标签: go escaping

这是我的测试代码。只需制作一个简单的http服务器。然后生成一个json数据,它的值是"&"。但结果是我不想要的。结果在代码块下面。

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
)

func testFunc(w http.ResponseWriter, r *http.Request) {
    data := make(map[string]string)
    data["key"] = "&"
    bytes, err := json.Marshal(data)
    if err != nil {
        fmt.Fprintln(w, "generator json error")
    } else {
        //print console
        fmt.Println(string(bytes))
        fmt.Println("&")
        //print broswer
        fmt.Fprintln(w, string(bytes))
        fmt.Fprintln(w, "&")
    }
}

func main() {
    http.HandleFunc("/", testFunc)
    err := http.ListenAndServe(":9090", nil)
    if err != nil {
        log.Fatal("ListenAndServe", err)
    }

}

结果: Chrome浏览器显示:

{"键":" \ u0026"}

&安培;

控制台还显示:

{"键":" \ u0026"}

&安培;

当' & '不在json中,浏览器和控制台将打印' & '。

4 个答案:

答案 0 :(得分:14)

在Go1.7中,他们have added有一个新选项可以解决此问题:

  

编码/ JSON:   添加Encoder.DisableHTMLEscaping这提供了一种禁用<,>和&的转义的方法。在JSON字符串中。

相关功能是

Dim c
For Each c In Selection
    If c.Value Like "* [A-Z,a-z][A-Z,a-z]######" Then _
        Debug.Print c.Value
Next c

应该应用于编码器

func (*Encoder) SetEscapeHTML

修改了stupidbodo的示例:https://play.golang.org/p/HnWGJAjqPA

答案 1 :(得分:12)

package main

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

type Search struct {
    Query string `json:"query"`
}

func main() {
    data := &Search{Query: "http://google.com/?q=stackoverflow&ie=UTF-8"}
    responseJSON, _ := JSONMarshal(data, true)
    fmt.Println(string(responseJSON))

}

func JSONMarshal(v interface{}, safeEncoding bool) ([]byte, error) {
    b, err := json.Marshal(v)

    if safeEncoding {
        b = bytes.Replace(b, []byte("\\u003c"), []byte("<"), -1)
        b = bytes.Replace(b, []byte("\\u003e"), []byte(">"), -1)
        b = bytes.Replace(b, []byte("\\u0026"), []byte("&"), -1)
    }
    return b, err
}

结果:

JSONMarshal(data, true)
{"query":"http://google.com/?q=stackoverflow&ie=UTF-8"}

JSONMarshal(data, false)
{"query":"http://google.com/?q=stackoverflow\u0026ie=UTF-8"}

致谢:https://github.com/clbanning/mxj/blob/master/json.go#L20

Playbook:http://play.golang.org/p/c7M32gICl8

答案 2 :(得分:4)

来自docs(我强调):

  

字符串值编码为JSON字符串。如果遇到无效的UTF-8序列,将返回InvalidUTF8Error。尖括号“&lt;”和“&gt;”被转义为“\ u003c”和“\ u003e”以防止某些浏览器将JSON输出误解为HTML。 &符号“&amp;”也出于同样的原因逃到“\ u0026”。

显然,如果你想发送'&amp;'因此,您需要创建自定义Marshaler,或者使用RawMessage类型:http://play.golang.org/p/HKP0eLogQX

答案 3 :(得分:1)

解决此问题的另一种方法是,在json.RawMessage调用之后,将json.Marshal()中的那些转义字符简单地替换为仅有效的UTF-8字符。

您可以使用strconv.Quote()strconv.Unquote()

func _UnescapeUnicodeCharactersInJSON(_jsonRaw json.RawMessage) (json.RawMessage, error) {
    str, err := strconv.Unquote(strings.Replace(strconv.Quote(string(_jsonRaw)), `\\u`, `\u`, -1))
    if err != nil {
        return nil, err
    }
    return []byte(str), nil
}

func main() {
    // Both are valid JSON.
    var jsonRawEscaped json.RawMessage   // json raw with escaped unicode chars
    var jsonRawUnescaped json.RawMessage // json raw with unescaped unicode chars

    // '\u263a' == '☺'
    jsonRawEscaped = []byte(`{"HelloWorld": "\uC548\uB155, \uC138\uC0C1(\u4E16\u4E0A). \u263a"}`) // "\\u263a"
    jsonRawUnescaped, _ = _UnescapeUnicodeCharactersInJSON(jsonRawEscaped)                        // "☺"

    fmt.Println(string(jsonRawEscaped))   // {"HelloWorld": "\uC548\uB155, \uC138\uC0C1(\u4E16\u4E0A). \u263a"}
    fmt.Println(string(jsonRawUnescaped)) // {"HelloWorld": "안녕, 세상(世上). ☺"}
}

https://play.golang.org/p/pUsrzrrcDG-

希望这会有所帮助。