响应

响应(Response):响应是服务器对客户端请求的回应。响应包含了状态码(表示请求是否成功,以及失败的原因)、响应头(包含一些元信息,如内容类型、设置cookie等)和响应体(包含服务器返回的数据)


import (  
    "github.com/gin-gonic/gin"  
)  
  
func str(context *gin.Context) {  
    context.String(200, "kasumi")  
}  
  
func _json(context *gin.Context) {  
  
    //type useinfo struct {  
    // usern string    // age   int    //}    //user := useinfo{"yaka", 18}    context.JSON(200, gin.H{"name": "kasumi", "age": 18})  
}  
  
// 响应yaml/xml  
func _xml(context *gin.Context) {  
    context.XML(200, gin.H{"name": "kasumi", "age": 18})  
}  
func _yaml(context *gin.Context) {  
    context.XML(200, gin.H{"name": "kasumi", "age": 19})  
}  
  
// 响应html  
func _html(context *gin.Context) {  
    context.HTML(200, "index.html", gin.H{"username": "kasumi"})  
}  
  
// 文件相应  
func _file(context *gin.Context) {  
    context.File("static/test.txt")  
}  
  
// 重定向  
func _redirect(context *gin.Context) {  
    context.Redirect(301, "https://www.baidu.com") // 301 永久重定向 302 临时重定向  
}  
  
func main() {  
    router := gin.Default()  
    router.LoadHTMLGlob("templates/*") // 加载模板目录下 所有模板文件  
    //router.Static("/static", "static")                   // 加载静态资源  
    router.StaticFile("/static/test", "static/test.txt") // 加载指定文件  
  
    router.GET("/", str)  
    router.GET("/json", _json)  
    router.GET("/xml", _xml)  
    router.GET("/yaml", _yaml)  
    router.GET("/html", _html)  
    router.GET("/file", _file)  
    router.GET("/redirect", _redirect)  
    err := router.Run(":8089")  
    if err != nil {  
       return  
  
    }  
}

请求参数

参数是请求中的一部分,用于向服务器传递额外的信息。参数可以出现在URL中(如查询参数或路径参数),也可以出现在请求体中(如表单数据或JSON数据)。参数的类型和格式取决于请求的内容类型和请求方法

查询参数


package main  
  
import (  
    "fmt"  
    "github.com/gin-gonic/gin")  
  
func query(context *gin.Context) {  
    name := context.Query("name")  
    age := context.Query("age")  
    //localhost:8089/query?name=kasumi&age=18  
    context.JSON(200, gin.H{"name": name, "age": age})  
    fmt.Println(name, age)  
}  
  
func main() {  
    router := gin.Default()  
    router.GET("/query", query)  
    err := router.Run(":8089")  
    if err != nil {  
       return  
    }  
}

动态参数


// 动态参数  
// 例如:http://localhost:8089/param/kasumi/22  
// 动态参数是在URL中的路径参数  
func param(context *gin.Context) {  
    name := context.Param("name")  
    age := context.Param("age")  
    context.JSON(200, gin.H{"name": name, "age": age})  
}

mainrouter.GET("/param/:name/:age/", param)

表单 PostForm


// 表单参数是在请求体中的参数,例如:http://localhost:8089/form  
// 表单参数是在请求体中的表单数据  
func form(context *gin.Context) {  
    name := context.PostForm("name")  
    age := context.PostForm("age")  
    //context.JSON(200, gin.H{"name": name, "age": age})  
    context.DefaultPostForm("name", "default")  
    context.DefaultPostForm("age", "default")  
    fmt.Println(name, age)  
  
}

mainrouter.POST("/form", form)

原始参数


// 原始参数是在请求体中的原始数据,例如:http://localhost:8089/raw  
// 原始参数是在请求体中的原始数据  
func raw(context *gin.Context) {  
    // 获取原始数据  
    data, err := context.GetRawData()  
    if err != nil {  
       return  
    }  
    contentType := context.GetHeader("Content-Type") // 获取请求头中的Content-Type  
    switch contentType {  
    case "application/json":  
       type jsonStruct struct {  
          Name string `json:"name"`  
          Age  int    `json:"age"`  
       }  
       var jsondata jsonStruct // 定义一个结构体  
       // 将原始数据转换为json数据  
       err := context.ShouldBindJSON(&jsondata)  
       if err != nil {  
          return  
       }  
       fmt.Println("json")  
  
    case "application/xml":  
       fmt.Println("xml")  
    }  
    fmt.Println(string(data))  
}

main router.POST("/raw", raw)

请求方式

当客户端(如浏览器)需要从服务器获取或发送数据时,它会向服务器发送一个请求。请求包含了一些信息,如请求方法(GET、POST等)、URL、请求头(包含一些元信息,如内容类型、认证信息等)和请求体(当使用POST或PUT等方法时,可以在请求体中发送数据)

RESTful是一种软件架构风格,它是Representational State Transfer(表现层状态转移)的缩写。RESTful架构主要用于客户端和服务器之间的交互,它基于HTTP协议,使用HTTP的请求方法来实现资源的增删改查。

  1. GET:用于获取资源。GET请求应该只是读取数据,并且不会对数据产生任何影响。

  2. POST:用于创建新的资源。POST请求通常会在服务器上创建新的资源,并且服务器会在响应中返回新资源的URI。

  3. PUT:用于更新资源。PUT请求会替换目标资源的所有当前表示。(客户端提供完整数据)

  4. DELETE:用于删除资源。DELETE请求会删除指定的资源。

  5. PATCH:用于部分更新资源。与PUT不同,PATCH请求只更新资源的部分内容。(提供需要修改的资源数据)

在RESTful架构中,每个URL代表一种资源,客户端和服务器之间,传递这种资源的某种表现层。客户端通过四个HTTP动词,对服务器端资源进行操作,实现”表现层状态转移”。


import (  
    "fmt"  
    "github.com/gin-gonic/gin")  
  
// 构造文章表  
type Article struct {  
    Id    int    `json:"id"`  
    Title string `json:"title"`  
}  
  
// 封装response  
type Response struct {  
    Code int         `json:"code"`  
    Msg  string      `json:"msg"`  
    Data interface{} `json:"data"`  
}  
  
// restful四大请求方式  
// GET:获取资源  
func getlist(context *gin.Context) {  
  
    // 构造数据  
    articles := []Article{  
       {Id: 1, Title: "文章1"},  
       {Id: 2, Title: "文章2"},  
       {Id: 3, Title: "文章3"},  
    }  
  
    context.JSON(200, Response{  
       Code: 200,  
       Msg:  "success",  
       Data: articles,  
    })  
}  
  
// GETDETAIL:获取资源详情  
func getdetail(context *gin.Context) {  
    // 获取参数(param的id)  
    id := context.Param("id")  
    fmt.Println(id)  
    article := Article{  
       Id:    1,  
       Title: "文章1",  
    }  
    context.JSON(200, Response{  
       Code: 200,  
       Msg:  "success",  
       Data: article,  
    })  
}  
  
// 剩下的需要用户传递参数  
// POST:创建资源  
func create(context *gin.Context) {  
    //context.JSON(200, gin.H{"method": "POST"})  
    // 就收前端传递的json数据  
    var article Article  
    err := context.ShouldBindJSON(&article)  
    if err != nil {  
       return  
    }  
    context.JSON(200, Response{  
       Code: 200,  
       Msg:  "success",  
       Data: article,  
    })  
}  
  
// PUT:更新资源  
func update(context *gin.Context) {  
    //context.JSON(200, gin.H{"method": "PUT"})  
    fmt.Println(context.Param("id"))  
    var article Article  
    err := context.ShouldBindJSON(&article)  
    if err != nil {  
       return  
    }  
  
    context.JSON(200, Response{  
       Code: 200,  
       Msg:  "success",  
       Data: article,  
    })  
  
}  
  
// DELETE:删除资源  
func delete(context *gin.Context) {  
    //context.JSON(200, gin.H{"method": "DELETE"})  
    fmt.Println(context.Param("id"))  
    context.JSON(200, Response{  
       Code: 200,  
       Msg:  "del success",  
       Data: nil,  
    })  
  
}  
  
func main() {  
    router := gin.Default()  
  
    //注册路由  
    router.GET("/list", getlist)  
    router.GET("/list/:id", getdetail)  
    router.POST("/list", create)  
    router.PUT("/list/:id", update)  
    router.DELETE("/list/:id", delete)  
  
    //启动服务  
    err := router.Run(":8080")  
    if err != nil {  
       return  
    }  
}

Ajax

Ajax(Asynchronous JavaScript and XML)是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。这意味着可以在网页上进行局部更新,而无需刷新整个页面。

展示如何在Go后端处理一个Ajax GET请求:

package main

import (
	"github.com/gin-gonic/gin"
)

func handleAjax(context *gin.Context) {
	// 获取Ajax请求的参数
	param := context.Query("param")

	// 返回JSON响应
	context.JSON(200, gin.H{
		"status": "success",
		"param":  param,
	})
}

func main() {
	router := gin.Default()
	router.GET("/ajax", handleAjax)
	router.Run(":8080")
}

定义处理函数handleAjax,获取Ajax请求的参数,并返回一个JSON响应。然后,在主函数中创建路由,将/ajax路径映射到handleAjax函数。

在前端JavaScript中,使用fetchaxios或者jQuery.ajax等方法来发送Ajax请求。例:

fetch('/ajax?param=value')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

/ajax路径发送了一个带有查询参数param=value的GET请求,然后处理返回的JSON响应。

bind 绑定参数

Gin提供了一系列的Bind函数,用于将请求的参数绑定到Go的结构体中。这些函数可以处理各种类型的请求和数据格式,包括JSON、XML、表单数据等。

常用的Bind函数:

  1. BindJSON(&struct): 此函数将请求的Body中的JSON数据绑定到结构体中。它首先检查Content-Type是否为application/json,然后使用json.Unmarshal将Body中的数据解析到结构体。

  2. BindQuery(&struct): 此函数将请求的查询参数绑定到结构体中。它使用url.Values解析查询参数,并将结果绑定到结构体。

  3. Bind(&struct): 此函数根据请求的Content-Type自动选择合适的绑定函数。例如,如果Content-Type为application/json,则使用BindJSON

这些函数都会返回一个错误,如果绑定过程中发生错误,检查并处理。

package main

import (
	"github.com/gin-gonic/gin"
)

type Login struct {
	User     string `form:"user" json:"user" binding:"required"`
	Password string `form:"password" json:"password" binding:"required"`
}

func main() {
	router := gin.Default()

	router.POST("/login", func(c *gin.Context) {
		var login Login
		if err := c.ShouldBindJSON(&login); err != nil {
			c.JSON(400, gin.H{"error": err.Error()})
			return
		}

		if login.User != "manu" || login.Password != "123" {
			c.JSON(401, gin.H{"status": "unauthorized"})
			return
		}

		c.JSON(200, gin.H{"status": "you are logged in"})
	})

	router.Run()
}

定义一个Login结构体,用于接收登录请求的参数。然后在/login路由的处理函数中,用c.ShouldBindJSON(&login)将请求的JSON数据绑定到Login结构体。如果绑定过程中发生错误,返回错误响应。如果绑定成功,检查用户名和密码,然后返回相应的响应。

分类:

更新时序:

笺評 (issue)