dongpai6567 2017-11-09 20:52
浏览 106
已采纳

从POST解析JSON

I've tried to be as descriptive as I can be. If I wasn't specific enough about something, please let me know and I will further explain.

Thanks in advance!

Explanation

I am trying to parse JSON data passed in the body of a POST request to my server. The client side request is being made from a web app written using React, the endpoint is on a server written in Go (code below). The server is correctly parsing the JSON data using a struct as a model, but only after it prints an error "unexpected end of JSON input" as well as an empty array (output below). I only print the parsed JSON once though, so I have no clue why this is happening. Also, if I follow up the POST with the same call multiple times, the behavior is correct sometimes.

The output of the log in the save function is:

[{user: "username", attribute: "playlist", match: true, value: "playlistID"}]

The output below was created when pressing the save button rapidly, therefore making the POST request many times. If I were to just press the save button once the output would be:

unexpected end of JSON input
[]
[{username playlist true playlistID}]

Output

[{username playlist true playlistID}]
[{username playlist true playlistID}]
unexpected end of JSON input
[]
[{username playlist true playlistID}]
[{username playlist true playlistID}]
[{username playlist true playlistID}]
[{username playlist true playlistID}]
[{username playlist true playlistID}]
[{username playlist true playlistID}]
[{username playlist true playlistID}]
[{username playlist true playlistID}]
[{username playlist true playlistID}]
[{username playlist true playlistID}]
unexpected end of JSON input
[]
[{username playlist true playlistID}]
[{username playlist true playlistID}]
[{username playlist true playlistID}]
[{username playlist true playlistID}]

Client Code

Save Button function

save = () => {
    var rules = [];
    this.state.rules.map((rule, index) => {
        var match = rule.matches[rule.state.match];
        var value = rule.values[rule.state.value];
        var newRule = {
            user: this.props.user,
            attribute: rule.attribute,
            match: match,
            value: value.UUID
        };
        rules.push(newRule);
        return newRule;
    });
    console.log(rules);
    Server.saveSmartPlaylist(rules);
};

Server from above

export function saveSmartPlaylist(data) {
    return axios({
        method: "POST",
        baseURL: "http://localhost:8080",
        url: "/smartplaylist",
        data: data
    }).catch(err => {
        console.log(err);
    });
}

Server Code

Endpoint function

func Playlists(response http.ResponseWriter, request *http.Request) {
    body, err := ioutil.ReadAll(request.Body)
    if err != nil {
        fmt.Println(err)
    }

    var rules []rule
    err = json.Unmarshal(body, &rules)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Println(rules)

    rest.PostRequest(response, request, rules)
}

Helper function

func PostRequest(response http.ResponseWriter, request *http.Request, v interface{}) {
    response.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    response.Header().Set("Access-Control-Allow-Origin", "*")
    response.Header().Set("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS")
    response.Header().Set("Content-Type", "application/json")

    enc := json.NewEncoder(response)
    enc.SetEscapeHTML(false)
    enc.Encode(v)
}
  • 写回答

2条回答 默认 最新

  • douyan4900 2017-11-09 21:36
    关注

    Guarding the actual usage of the parsed JSON inside an if that checks the request method solved my problem.

    func Playlists(response http.ResponseWriter, request *http.Request) {
        var rules []rule
        if request.Method == http.MethodPost {
            body, err := ioutil.ReadAll(request.Body)
            if err != nil {
                fmt.Println(err)
            }
    
            err = json.Unmarshal(body, &rules)
            if err != nil {
                fmt.Println(err)
            }
    
            var tracks []string
            var userID string
            for i := 0; i < len(rules); i++ {
                rule := rules[i]
                ruleTracks := PlaylistMatchValue(rule.User, rule.Match, rule.Value)
                tracks = ruleTracks
                userID = rule.User
            }
    
            updatePlaylist(userID, tracks)
        }
    
        rest.PostRequest(response, request, rules)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法