如何在 POST 的前端发送信息到 Gin 和 Go 的后端

How to send information in frontend with POST to backend with Gin and Go

我通常在表单中发送数据,从来没有任何问题,但现在我需要使用 JavaScript 发送数据,而我无法在后端读取它。

我的 main.go 文件:

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)
}

我的 HTML 文件,位于同一目录中:

<!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>

我尝试将 headers 从 application/json 换成 application/x-www-form-urlencoded 但没有成功。 在浏览器中重新加载页面后,我在控制台中得到的答案(以及 JavaScript 中的方法 afterLoad() 被执行)是:

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:

此数据打印自 main.go 文件中的 getData() 函数。我做错了什么获取不到数据?

我看到两个问题。首先,formData 是指向结构的指针,当您使用 decode 时,您会得到已经是地址的地址。其次,你的struct没有带mydata的json标签,只有一个form标签,这不足以让json.Decode将json属性映射到struct属性.将 form 标签更改为 json 标签