Difficult to decode JSON from http form POST

528 views
Skip to first unread message

andbelo

unread,
Sep 28, 2015, 12:57:29 PM9/28/15
to golang-nuts
Hello golang-nuts,

I am having difficulties in decoding JSON from a http form POST and could not find the solution anywhere so I decided to ask for help here. It might be a silly mistake but I am not being able to sort this out.

The "page.html" I have is:

<!DOCTYPE html>
<html>
   
<head>
       
<meta charset="UTF-8">
       
<title>Title of page</title>
   
</head>
   
<body>
       
<form enctype='application/json' method="post">
           
<select name="Letter">
               
<option value="Default"></option>
               
<option value="A">A</option>
               
<option value="B">B</option>
           
</select>
           
<input type='submit' value="Submit">
       
</form>
   
</body>
</html>

and the go server, compiled to server.exe, is:

package main


import (
 
"encoding/json"
 
"log"
 
"net/http"
)


type t
struct {
 
Letter string
}


func page
(w http.ResponseWriter, r *http.Request) {
 log
.Printf("r: %v\n", r)
 
if r.Method == "POST" {
 dec
:= json.NewDecoder(r.Body)
 v
:= &t{}
 e
:= dec.Decode(v)
 
if e != nil {
 log
.Println(e)
 
}
 log
.Printf("v: %#v\n", v)
 
}
 http
.ServeFile(w, r, "page.html")
}


func main
() {
 http
.HandleFunc("/", page)
 log
.Fatal(http.ListenAndServe(":8082", nil))
}

When I run this in a terminal, access http://localhost:8082/, fill and submit the form, I have:

C:\>server.exe

2015/09/28 11:50:52 r: &{GET / HTTP/1.1 1 1 map[Cache-Control:[max-age=0] Accept:[text/html,applicat
ion/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8] User-Agent:[Mozilla/5.0 (Windows NT 6.1; W
OW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36] Https:[1] Accept-Enc
oding:[gzip, deflate, sdch] Accept-Language:[en-US,en;q=0.8,pt;q=0.6] Connection:[keep-alive]] 0x8b0
a10 0 [] false localhost:8082 map[] map[] <nil> map[] [::1]:53593 / <nil> <nil>}

2015/09/28 11:51:20 r: &{POST / HTTP/1.1 1 1 map[Content-Type:[application/x-www-form-urlencoded] Ca
che-Control:[max-age=0] User-Agent:[Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, l
ike Gecko) Chrome/44.0.2403.89 Safari/537.36] Https:[1] Accept:[text/html,application/xhtml+xml,appl
ication/xml;q=0.9,image/webp,*/*;q=0.8] Origin:[http://localhost:8082] Referer:[http://localhost:808
2/] Accept-Encoding:[gzip, deflate] Accept-Language:[en-US,en;q=0.8,pt;q=0.6] Connection:[keep-alive
] Content-Length:[8]] 0xc0821b1bc0 8 [] false localhost:8082 map[] map[] <nil> map[] [::1]:53593 / <
nil> <nil>}

2015/09/28 12:21:28 r.Body: &{0xc082204c00 <nil> <nil> false true {0 0} false false false}

2015/09/28 12:21:28 invalid character 'L' looking for beginning of value

2015/09/28 12:21:28 v: &main.t{Letter:""}

If someone could give a hint, that would be very appreciated.
Thanks a lot!

Henrik Johansson

unread,
Sep 28, 2015, 1:12:23 PM9/28/15
to andbelo, golang-nuts
But an ordinary form post like that will not generate valid JSON.
To parse a form you have to use the ParseForm(req) method or send the payload as actual json.


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Andy Balholm

unread,
Sep 28, 2015, 1:32:00 PM9/28/15
to andbelo, golang-nuts
Your browser apparently does not support a value of application/json for the enctype attribute (I don’t know if any actually do). So it falls back to the default, which is application/x-www-form-urlencoded. You can see that in the Content-Type header that your program logged.

In other words, HTML forms don’t generate JSON, so you need to deal with the encoding that they do generate.

Andy

Matt Silverlock

unread,
Sep 28, 2015, 5:38:40 PM9/28/15
to golang-nuts, and...@gmail.com
> In other words, HTML forms don’t generate JSON, so you need to deal with the encoding that they do generate. 

This.

One approach would be to have a struct with tags for gorilla/schema (http://www.gorillatoolkit.org/pkg/schema - or similar) and encoding/json — decode the PostForm into the struct, and then you can turn the struct into JSON for storage or re-transmission as you see fit.

André Beló

unread,
Sep 28, 2015, 6:23:09 PM9/28/15
to golang-nuts
Thank you for your comments!

As this is not really a go issue, I will parse the form from the Post, and then loop over the key:values. It will be easier for me to workaround in the code of my go server.

I thought that if the browser was able to generate that as mentioned somewhere in W3C a simple JSON decoding would be the best solution. It came out too good to be true!

Thank you again and best regards.
Reply all
Reply to author
Forward
0 new messages