이스케이프된 JSON 문자열을 마킹 해제하는 방법
Go와 함께 Sockjs를 사용하고 있는데 JavaScript 클라이언트가 서버에 json을 전송하면 json이 이스케이프되어 []바이트로 전송됩니다.데이터를 읽을 수 있도록 json을 해석하는 방법을 찾고 있지만 오류가 발생합니다.
json: 문자열을 main 형식의 Go 값으로 변환할 수 없습니다.메시지
어떻게 하면 고칠 수 있을까요? html.UnescapeString()효과가 없습니다.
val, err := session.ReadMessage()
if err != nil {
break
}
var msg Msg
err = json.Unmarshal(val, &msg)
fmt.Printf("%v", val)
fmt.Printf("%v", err)
type Msg struct {
Channel string
Name string
Msg string
}
//Output
"{\"channel\":\"buu\",\"name\":\"john\", \"msg\":\"doe\"}"
json: cannot unmarshal string into Go value of type main.Msg
먼저 JSON 문자열에서 를 사용하는 것이 좋습니다.
package main
import (
"encoding/json"
"fmt"
"strconv"
)
type Msg struct {
Channel string
Name string
Msg string
}
func main() {
var msg Msg
var val []byte = []byte(`"{\"channel\":\"buu\",\"name\":\"john\", \"msg\":\"doe\"}"`)
s, _ := strconv.Unquote(string(val))
err := json.Unmarshal([]byte(s), &msg)
fmt.Println(s)
fmt.Println(err)
fmt.Println(msg.Channel, msg.Name, msg.Msg)
}
JSON을 생성하는 코드에서 이 문제를 수정해야 합니다.
이렇게 포맷되어 있으면 JSON이 2회 인코딩되어 있는 것입니다.생성 중인 코드를 수정하여 한 번만 발생하도록 합니다.
여기 무슨 일이 일어나고 있는지 보여주는 자바스크립트가 있습니다.
// Start with an object
var object = {"channel":"buu","name":"john", "msg":"doe"};
// serialize once
var json = JSON.stringify(object); // {"channel":"buu","name":"john","msg":"doe"}
// serialize twice
json = JSON.stringify(json); // "{\"channel\":\"buu\",\"name\":\"john\",\"msg\":\"doe\"}"
가끔씩,strconv.Unquote동작하지 않습니다.
다음은 문제와 해결 방법을 보여 주는 예입니다.(놀이터 링크: https://play.golang.org/p/Ap0cdBgiA05)
@Crazy Train의 "두 번 암호화" 아이디어 덕분에 두 번 복호화했습니다.
package main
import (
"encoding/json"
"fmt"
"strconv"
)
type Wrapper struct {
Data string
}
type Msg struct {
Photo string
}
func main() {
var wrapper Wrapper
var original = `"{\"photo\":\"https:\/\/www.abc.net\/v\/t1.0-1\/p320x320\/123.jpg\"}"`
_, err := strconv.Unquote(original)
fmt.Println(err)
var val []byte = []byte("{\"data\":"+original+"}")
fmt.Println(string(val))
err = json.Unmarshal([]byte(val), &wrapper)
fmt.Println(wrapper.Data)
var msg Msg
err = json.Unmarshal([]byte(wrapper.Data), &msg)
fmt.Println(msg.Photo)
}
Crazy Train이 지적한 바와 같이 입력이 이중으로 이스케이프되어 문제가 발생하고 있는 것 같습니다.이 문제를 해결하는 한 가지 방법은 기능이session.ReadMessasge()는 적절히 이스케이프된 적절한 출력을 반환합니다.단, 그것이 불가능할 경우 x3ro가 제안한 것을 언제든지 실행해 골랑 기능을 사용할 수 있습니다.strconv.Unquote.
다음은 실제 가동 중인 놀이터의 예입니다.
http://play.golang.org/p/GTishI0rwe
이 문제에 나타난 데이터는 어떤 목적으로 문자열화되어 있으며 경우에 따라서는 문자열에 \n이 json의 줄 바꿈을 나타낼 수도 있습니다.
다음 예제를 사용하여 이러한 종류의 데이터의 마샬화/직렬화를 해제하는 가장 쉬운 방법에 대해 설명합니다.
다음 행은 소스로부터 취득한 데이터이며, 데어리얼라이즈 하고 싶은 데이터를 나타내고 있습니다.
stringized Data : = "{\r\n "a\", "b\", \r\n "c\", "d"\r\n"
이제 모든 새 줄을 먼저 제거합니다.
stringizedData = 문자열입니다.Replace All(stringified Data, "\n", ")
그런 다음 문자열에 있는 모든 추가 따옴표를 제거합니다.
stringizedData = 문자열입니다.Replace All(stringified Data, "\"", "\")
이제 문자열을 바이트 배열로 변환합니다.
dataInBytes : = [ ]byte ( stringifiedData )
마셜을 해제하기 전에 데이터 구조를 정의합니다.
& param{ : = & param{
"json: "a"
문자열 " C 'json: "c"
}이제 값을 jsonObject로 직렬화할 수 있습니다.
json.Unmarshal(dataInBytes, jsonObject)}
당신은 JavaScript에서 악명 높은 탈출 문자열 함정에 빠졌습니다.JSON 스트링을 json과 시리얼화할 때 Go에서도 (저와 마찬가지로) 동일한 문제에 직면하는 경우가 많습니다.보안관님, 예:
in := `{"firstName":"John","lastName":"Dow"}`
bytes, err := json.Marshal(in)
json.Marshal은 이중 따옴표를 사용하지 않으므로 바이트를 구조화하려고 할 때 동일한 문제가 발생합니다.
Go에서 이 문제에 직면한 경우 해결 방법에 대한 자세한 내용은 Golang 게시물에서 JSON String을 올바르게 직렬화하는 방법을 참조하십시오.
언급URL : https://stackoverflow.com/questions/16846553/how-to-unmarshal-an-escaped-json-string
'programing' 카테고리의 다른 글
| 오류: ENOENT: 해당 파일 또는 디렉터리가 없습니다. 오류(네이티브)에서 '/public/main.html'을 stat합니다. (0) | 2023.03.06 |
|---|---|
| WordPress 플러그인을 디버깅하려면 어떻게 해야 합니까? (0) | 2023.03.06 |
| YAML을 사용한 Spring @PropertySource (0) | 2023.03.06 |
| Java EE 6 대스프링 3 스택 (0) | 2023.03.06 |
| json 파일을 찾을 수 없는 이유는 무엇입니까? (0) | 2023.03.06 |