这是我的测试代码。只需制作一个简单的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中,浏览器和控制台将打印' & '。
答案 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-
希望这会有所帮助。