I normally send data within forms, and never had any problem, but now I need to send the data with JavaScript, and I am not able to read it in the backend.
My main.go file:
package main
import (
"encoding/json"
"fmt"
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
// We create the instance for Gin
r := gin.Default()
// Path to the static files. /static is rendered in the HTML and /media is the link to the path to the images, svg, css.. the static files
r.StaticFS("/static", http.Dir("../media"))
// Path to the HTML templates. * is a wildcard
r.LoadHTMLGlob("*.html")
r.NoRoute(renderHome)
// This get executed when the users gets into our website in the home domain ("/")
r.GET("/", renderHome)
r.POST("/", getData)
r.Run(":8080")
}
func renderHome(c *gin.Context) {
c.HTML(http.StatusOK, "my-html.html", gin.H{})
}
func getData(c *gin.Context) {
formData := &struct {
Name string `json:"mydata" binding:"required" `
}{}
// Validation (with Gin)
if err := c.Bind(formData); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
fmt.Print(err)
return
}
fmt.Println("formData: ", formData.Name)
dec := json.NewDecoder(c.Request.Body)
fmt.Println("Decooder: ", dec)
dec.Decode(formData)
fmt.Println("formData: ", formData.Name)
p := c.PostForm("mydata")
fmt.Println("Params: ", p)
p = c.Params.ByName("mydata")
fmt.Println("Params: ", p)
p, _ = c.Params.Get("mydata")
fmt.Println("Get: ", p)
fmt.Println("Body: ", c.Request.Body)
}
My HTML file, located in the same directory:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body onload="afterLoad()" style="background-color: pink">
<script>
async function postData(url = "", data = {}) {
// Opciones por defecto estan marcadas con un *
const response = await fetch(url, {
method: "POST",
mode: "cors",
cache: "no-cache",
credentials: "same-origin",
headers: {
// "Content-Type": "application/json",
"Content-Type": "application/x-www-form-urlencoded",
},
redirect: "follow",
referrerPolicy: "no-referrer",
body: JSON.stringify(data),
});
return response.json(); // parses JSON response into native JavaScript objects
}
function afterLoad() {
postData("/", { mydata: 42 }).then((data) => {
console.log(data); // JSON data parsed by `data.json()` call
});
}
</script>
</body>
</html>
I tried to interchange the headers from application/json
to application/x-www-form-urlencoded
but no luck.
The answer I get in the console after reloading the page in the browser (and the method afterLoad()
from JavaScript gets executed) is:
formData:
Decooder: &{0xc0002b7580 [] {[] 0 0 {<nil> false [] <nil> 0} {<nil> []} <nil> false false} 0 0 {<nil> false [] <nil> 0} <nil> 0 []}
formData:
Params:
Params:
Get:
This data is printed from the getData()
func in main.go
file. What I am doing wrong to not be able to get the data?
I see two problems. First, formData
is a pointer to struct and when you use decode you get the address of something that's already an address. Second, your struct doesn't have a json tag with mydata
, just a form tag, which is not enough for json.Decode to map the json attribute to the struct attribute. Change the form
tag for a json
tag