如何显示字符而不是 ASCII 码?

huangapple go评论101阅读模式
英文:

How to display a character instead of ascii?

问题

这是我的测试代码。只是创建了一个简单的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, "生成JSON错误")
	} else {
		// 在控制台打印
		fmt.Println(string(bytes))
		fmt.Println("&")
		// 在浏览器中打印
		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浏览器显示:

{"key":"\u0026"}
&

控制台也显示:

{"key":"\u0026"}
&

当JSON中没有&时,浏览器和控制台将打印&

英文:

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 &.

答案1

得分: 27

在Go1.7中,他们添加了一个新选项来解决这个问题:
> encoding/json:
> 添加了Encoder.DisableHTMLEscaping。这提供了一种在JSON字符串中禁用<、>和&转义的方法。

相关的函数是

func (*Encoder) SetEscapeHTML

应该应用于Encoder

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

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

英文:

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

答案2

得分: 17

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


<details>
<summary>英文:</summary>

    package main
    
    import (
        &quot;bytes&quot;
        &quot;encoding/json&quot;
        &quot;fmt&quot;
    )
    
    type Search struct {
        Query string `json:&quot;query&quot;`
    }
    
    func main() {
        data := &amp;Search{Query: &quot;http://google.com/?q=stackoverflow&amp;ie=UTF-8&quot;}
        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(&quot;\\u003c&quot;), []byte(&quot;&lt;&quot;), -1)
            b = bytes.Replace(b, []byte(&quot;\\u003e&quot;), []byte(&quot;&gt;&quot;), -1)
            b = bytes.Replace(b, []byte(&quot;\\u0026&quot;), []byte(&quot;&amp;&quot;), -1)
        }
        return b, err
    }


Results:

    JSONMarshal(data, true)
    {&quot;query&quot;:&quot;http://google.com/?q=stackoverflow&amp;ie=UTF-8&quot;}
    
    JSONMarshal(data, false)
    {&quot;query&quot;:&quot;http://google.com/?q=stackoverflow\u0026ie=UTF-8&quot;}

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

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


</details>



# 答案3
**得分**: 4

从[文档](http://golang.org/pkg/encoding/json/#Marshal)中(我加了重点):

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

显然,如果你想原样发送'&',你需要创建一个自定义的Marshaler,或者使用[RawMessage](golang.org/pkg/encoding/json/#RawMessage)类型,像这样:http://play.golang.org/p/HKP0eLogQX。

<details>
<summary>英文:</summary>

From the 
(http://golang.org/pkg/encoding/json/#Marshal) (emphasis by me): &gt;String values encode as JSON strings. InvalidUTF8Error will be returned if an invalid UTF-8 sequence is encountered. The angle brackets &quot;&lt;&quot; and &quot;&gt;&quot; are escaped to &quot;\u003c&quot; and &quot;\u003e&quot; to keep some browsers from misinterpreting JSON output as HTML. **Ampersand &quot;&amp;&quot; is also escaped to &quot;\u0026&quot; for the same reason.** Apparently if you want to send &#39;&amp;&#39; as is, you&#39;ll need to either create a custom Marshaler, or use [RawMessage](golang.org/pkg/encoding/json/#RawMessage) type like this: http://play.golang.org/p/HKP0eLogQX. </details> # 答案4 **得分**: 2 解决这个问题的另一种方法是,在`json.Marshal()`调用之后,将[`json.RawMessage`][1]中的转义字符替换为有效的UTF-8字符。 你可以使用[`strconv.Quote()`][3]和[`strconv.Unquote()`][4]来实现。 ```go 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 // '&#39;\u263a&#39;' == '&#39;☺&#39;' jsonRawEscaped = []byte(`{&quot;HelloWorld&quot;: &quot;\uC548\uB155, \uC138\uC0C1(\u4E16\u4E0A). \u263a&quot;}`) // &quot;\\u263a&quot; jsonRawUnescaped, _ = _UnescapeUnicodeCharactersInJSON(jsonRawEscaped) // &quot;☺&quot; fmt.Println(string(jsonRawEscaped)) // {&quot;HelloWorld&quot;: &quot;\uC548\uB155, \uC138\uC0C1(\u4E16\u4E0A). \u263a&quot;} fmt.Println(string(jsonRawUnescaped)) // {&quot;HelloWorld&quot;: &quot;안녕, 세상(世上). ☺&quot;} }

希望对你有所帮助。

英文:

Another way to solve the problem is to simply replace those escaped characters in json.RawMessage into just valid UTF-8 characters, after the json.Marshal() call.

You can use the strconv.Quote() and strconv.Unquote() to do so.

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

    // &#39;\u263a&#39; == &#39;☺&#39;
    jsonRawEscaped = []byte(`{&quot;HelloWorld&quot;: &quot;\uC548\uB155, \uC138\uC0C1(\u4E16\u4E0A). \u263a&quot;}`) // &quot;\\u263a&quot;
    jsonRawUnescaped, _ = _UnescapeUnicodeCharactersInJSON(jsonRawEscaped)                        // &quot;☺&quot;

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

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

Hope this helps.

huangapple
  • 本文由 发表于 2014年7月9日 22:36:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/24656624.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定