Golang - символ отображения, а не ascii. Подобно '&', а не '\ 0026'
Это мой тестовый код. Просто создайте простой 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, браузер и консоль будут печатать " &".
Ответы
Ответ 1
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
В Go1.7 добавили новый параметр, чтобы исправить это:
кодирования/JSON: add Encoder.DisableHTMLEscaping Это дает возможность отключить экранирование строк <, > и и в JSON.
Соответствующая функция
func (*Encoder) SetEscapeHTML
Это должно быть применено к Encoder.
enc := json.NewEncoder(os.Stdout)
enc.SetEscapeHTML(false)
Пример модификации stupidbodo: https://play.golang.org/p/HnWGJAjqPA
Ответ 3
Из docs (выделение мной):
Строковые значения кодируются как строки JSON. InvalidUTF8Error будет возвращен, если встречается некорректная последовательность UTF-8. Угловые скобки "<" и " > " экранируются до "\ u003c" и "\ u003e", чтобы некоторые браузеры неправильно интерпретировали вывод JSON как HTML. Амперсанд "&" по той же причине также экранируется "\ u0026".
Видимо, если вы хотите отправить '&' как и вам, вам нужно создать пользовательский маршалер или использовать тип RawMessage следующим образом: http://play.golang.org/p/HKP0eLogQX.