programing

이스케이프된 JSON 문자열을 마킹 해제하는 방법

newnotes 2023. 3. 6. 21:27
반응형

이스케이프된 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 문자열에서 를 사용하는 것이 좋습니다.

다음은 @greghz에서 제공하는 입니다.

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의 줄 바꿈을 나타낼 수도 있습니다.

다음 예제를 사용하여 이러한 종류의 데이터의 마샬화/직렬화를 해제하는 가장 쉬운 방법에 대해 설명합니다.

  1. 다음 행은 소스로부터 취득한 데이터이며, 데어리얼라이즈 하고 싶은 데이터를 나타내고 있습니다.

    stringized Data : = "{\r\n "a\", "b\", \r\n "c\", "d"\r\n"

  2. 이제 모든 새 줄을 먼저 제거합니다.

    stringizedData = 문자열입니다.Replace All(stringified Data, "\n", ")

  3. 그런 다음 문자열에 있는 모든 추가 따옴표를 제거합니다.

    stringizedData = 문자열입니다.Replace All(stringified Data, "\"", "\")

  4. 이제 문자열을 바이트 배열로 변환합니다.

    dataInBytes : = [ ]byte ( stringifiedData )

  5. 마셜을 해제하기 전에 데이터 구조를 정의합니다.

    & param{ : = & param{
    "json: "a"
    문자열 " C 'json: "c"
    }

  6. 이제 값을 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

반응형