Go高级之Gin框架中POST参数的提取(二)

2023-11-05 20:31:35 浏览数 (1)

前言

本文是探讨的是"Go高级之Gin框架中POST参数的提取"

此文章是个人学习归纳的心得,未经允许,严禁转载,如有不对, 还望斧正, 感谢!

关于POST请求的基础知识

POST请求是一种HTTP请求方法,常用于用于向指定的资源提交要被处理的数据。与GET请求不同,POST请求将数据包含在请求的消息体(body)中,而不是在URL的查询参数中。通过POST请求,可以向服务器发送数据,这些数据可以是表单数据、JSON数据、文件等。

请求的消息体(body)是POST请求中包含的数据部分。它通常用于向服务器发送数据,供服务器进行处理或存储。消息体可以包含各种格式的数据,如表单数据、JSON数据、XML数据等,具体取决于请求的内容类型(Content-Type)。

在HTTP请求中,请求头(headers)中的Content-Type字段用于指示请求的消息体的数据格式。常见的Content-Type类型包括:

  • application/x-www-form-urlencoded:用于传输经过URL编码的表单数据,常用于HTML表单提交。
  • application/json:用于传输JSON格式的数据。
  • multipart/form-data:用于传输带有文件上传的表单数据。

例如,使用POST请求提交表单数据时,请求通常具有以下特征:

  • 请求方法:POST
  • 请求URL:指定要提交数据的目标资源的URL
  • 请求头(headers):Content-Type设置为application/x-www-form-urlencoded或multipart/form-data
  • 请求的消息体(body):包含通过表单填写的数据字段和值

示例请求的消息体(body)内容(使用Content-Type为application/x-www-form-urlencoded):

代码语言:txt复制
name=John Doe&email=john@example.com&age=25

示例请求的消息体(body)内容(使用Content-Type为application/json):

代码语言:txt复制
{

  "name": "John Doe",

  "email": "john@example.com",

  "age": 25

}

通过POST请求和请求的消息体(body),可以向服务器发送数据并执行相应的操作,例如创建新的资源、更新已有资源等。服务器端的代码需要解析请求的消息体,提取相应的数据进行处理。

注意

注意! 无论是表单还是地址栏,默认的请求方式都是GET请求,我们想使用POST请求,一般有两种方法:

  • 第一种就是在使用表单的时候,指定请求方式为POST。
  • 另外一种就是自己写请求,并且指定请求方法为POST请求。

表单的话,如果不指定为POST请求的话,收集的参数会以get请求中query的形式传给服务器。

在Gin框架中使用数据绑定来提取POST请求的body的数据

手写一个简单的Gin服务器

我们先写一个简单的Gin服务器,其中端口设置为9090

代码语言:txt复制
package demo



import (

   "fmt"

   "github.com/gin-gonic/gin"

)



// 定义结构体,解析post请求携带的body数据,通常使用数据绑定的操作

type UserDemo struct {

   Name string `json:"name"`

   Age  int    `json:"age"`

}



func ServerDemo() {

   server := gin.Default()  // 创建一个gin服务器实例

   server.LoadHTMLGlob("demo/HTML/*")  // 读取demo文件夹下面的HTML文件夹下面的所有的html文件



   //返回index.html

   server.GET("/demo", func(c *gin.Context) {

      c.HTML(200, "index.html", nil)

   })



   //返回index.html

   server.GET("/demo2", func(c *gin.Context) {

      c.HTML(200, "index2.html", nil)

   })



   // 定义一个post请求的路由

   server.POST("/demo3", func(c *gin.Context) {

      user := UserDemo{} //创建一个前面定义好的实例  

      err := c.ShouldBind(&user)  //进行数据绑定,把请求体里面的参数,通过`josn:"name"`和`json:"age"`标识,绑定到结构体的字段中去

      

      fmt.Printf("this is % vn", user)

      if err != nil {

         c.String(500, "Error")

      } else {

         c.String(200, "ok")

      }

   })



   server.Run(":9090")

}

HTML部分代码

然后是HTML文件夹下的内容,其中HTML文件夹和上面的go文件是同一级,你看我写的package应该就知道了

这是index.html,就是一个简单的表单,提交的路由是前面定义好了的post路由

代码语言:html复制
{{define "index.html"}}

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>Title</title>

</head>

<body>

<h1>这是demo</h1>

   <form action="/demo3" method="post">

       <input type="text" name="Name">

       <input type="number" name="Age">

       <button type="submit">提交</button>

   </form>

</body>

</html>

{{end}}

然后是index2.html 这里主要是用axios发了一个post请求

代码语言:txt复制
{{ define "index2.html"}}

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>Title</title>

    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

</head>

<body>



<input type="text" name="name">

<input type="number" name="age">

<button type="button">提交2</button>



<script>

    document.querySelector("button").addEventListener('click', function(event) {

        const name = document.querySelectorAll("input")[0].value

        let age =  document.querySelectorAll("input")[1].value

        console.log('this is is',name,age,typeof age)

        axios.post("/demo3",{

            Name:name,

            Age:age

        }).then((response)=>{

            console.log(response);

        },(error)=>{

            console.log(error);

        })

    });



</script>

</body>

</html>

{{end}}

测试

运行一下

然后我们在浏览器开两个页面,访问一下两个路由

我们先用demo试一下,结果如下,我们成功捕获到了

再用 demo2试一下

小结

在HTML表单中,当使用<form>元素并设置methodpost时,浏览器会将表单数据作为请求体的一部分发送到指定的action URL。请求体的格式是application/x-www-form-urlencoded,其中包含通过表单中的输入字段收集到的键值对数据。

而使用Axios库发起的POST请求,你可以自定义请求体的数据格式。在我提供的示例中,我使用了Axios的post方法,并将一个对象作为第二个参数传递。这个对象表示要发送到服务器的数据。Axios默认会将这个对象转换为JSON格式,并将其作为请求体发送。请求的Content-Type会被设置为application/json

所以,主要的区别在于请求体的格式和Content-Type。HTML表单使用的是application/x-www-form-urlencoded格式,而Axios使用的是application/json格式。

在服务器端,我们可以根据请求的Content-Type选择适当的方式来解析请求体数据。对于application/x-www-form-urlencoded格式,可以使用c.ShouldBindc.ShouldBindWith方法来解析请求体数据。对于application/json格式,可以使用c.ShouldBindJSON方法来解析请求体数据。

但是其实,我们用c.ShouldBind()就行了,这个函数会先进行Content-Type的判断,然后决定下一步操作

注意

  • 在前端界面中,如果不是通过表单来发送post请求的话,而是用axios的话,界面中所有用户输入的东西,格式都是string类型的,你如果要想正确绑定,那你的数据格式就要和type定义的类型一样,感觉有点像是废话,也确实是废话,实际前端开发中,一般是用axios或者什么库,基本上不会使用默认的事件

对了,我近期要用Gin框架 Vue3 js MongoDB写一个个人博客网站的小实践,前后端分离,前后端都是自己来写,我将全程记录,从网站的UI设计,HTML、CSS实现,再到网站的整体架构,再到具体的细节的实现,这也是对Gin框架的一次实践,欢迎关注我的后续动态。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

0 人点赞