Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display a character instead of ascii?

Tags:

json

escaping

go

This is my testing code. Just make a simple HTTP server. Then generating a JSON data that it values is "&". But the result is what I don't want. The result is below the code block.

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)
    }

}

result: Chrome browser show:

{"key":"\u0026"}
&

Console also show:

{"key":"\u0026"}
&

When & not in JSON, browser and console will print &.

like image 287
huazi Avatar asked Jul 09 '14 14:07

huazi


3 Answers

In Go1.7 they have added a new option to fix this:

encoding/json: add Encoder.DisableHTMLEscaping This provides a way to disable the escaping of <, >, and & in JSON strings.

The relevant function is

func (*Encoder) SetEscapeHTML

That should be applied to a Encoder.

enc := json.NewEncoder(os.Stdout)
enc.SetEscapeHTML(false)

The example of stupidbodo modified: https://play.golang.org/p/HnWGJAjqPA

like image 163
adrianlzt Avatar answered Nov 18 '22 10:11

adrianlzt


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
}

Results:

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

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

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

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

like image 16
stupidbodo Avatar answered Nov 18 '22 11:11

stupidbodo


From the docs (emphasis by me):

String values encode as JSON strings. InvalidUTF8Error will be returned if an invalid UTF-8 sequence is encountered. The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e" to keep some browsers from misinterpreting JSON output as HTML. Ampersand "&" is also escaped to "\u0026" for the same reason.

Apparently if you want to send '&' as is, you'll need to either create a custom Marshaler, or use RawMessage type like this: http://play.golang.org/p/HKP0eLogQX.

like image 4
Ainar-G Avatar answered Nov 18 '22 12:11

Ainar-G