英文:
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 (
"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
</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):
>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](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
// ''\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": "안녕, 세상(世上). ☺"}
}
希望对你有所帮助。
英文:
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
// '\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-
Hope this helps.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论