Gin 接收前端传参方式有几种?

Gin 接收前端传参方式有几种?

路径参数(RESTful 风格必用)

参数在 URL 路径里,比如 /user/123。

c.Param(key string) string

  • 作用:从 URL 路径中提取定义好的参数值
  • 参数 :key 是路由中定义的路径变量名(如 :id 中的 id)
  • 返回值:字符串类型的参数值
go 复制代码
package main

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

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

	// 定义路由::id 是路径参数
	r.GET("/user/:id", func(c *gin.Context) {
		// 使用 c.Param() 获取路径参数
		id := c.Param("id")
		c.JSON(200, gin.H{
			"用户ID": id,
		})
	})

	r.Run(":8080")
}

访问:http://127.0.0.1:8080/user/1001返回:{"用户ID":"1001"}

查询字符串(Query 参数)

参数在 URL 问号后面,比如 /search?keyword=golang&page=1。

c.Query(key string) string

  • 作用:获取 URL 查询参数
  • 参数 :key 是查询参数的键名
  • 返回值:字符串类型的参数值;若参数不存在,返回空字符串

c.DefaultQuery(key, defaultValue string) string

  • 作用:获取 URL 查询参数,带默认值

  • 参数:

    • key:查询参数的键名
    • defaultValue:参数不存在时的默认值
  • 返回值 :字符串类型的参数值;若参数不存在,返回 defaultValue

go 复制代码
r.GET("/search", func(c *gin.Context) {
	// 1. 普通获取(没传就是空字符串)
	keyword := c.Query("keyword")

	// 2. 带默认值获取
	page := c.DefaultQuery("page", "1")

	c.JSON(200, gin.H{
		"关键词": keyword,
		"页码":   page,
	})
})

访问:http://127.0.0.1:8080/search?keyword=Gin返回:{"关键词":"Gin","页码":"1"}

表单数据(Form 表单)

前端用 <form> 提交,或者 Postman 选 x-www-form-urlencoded。

c.PostForm(key string) string

  • 作用:获取 POST 表单数据
  • 参数 :key 是表单字段名
  • 返回值:字符串类型的字段值;若字段不存在,返回空字符串

c.DefaultPostForm(key, defaultValue string) string

  • 作用:获取 POST 表单数据,带默认值

  • 参数:

    • key:表单字段名
    • defaultValue:字段不存在时的默认值
  • 返回值 :字符串类型的字段值;若字段不存在,返回 defaultValue

go 复制代码
r.POST("/login", func(c *gin.Context) {
	// 1. 普通获取
	username := c.PostForm("username")

	// 2. 带默认值
	password := c.DefaultPostForm("password", "123456")

	c.JSON(200, gin.H{
		"账号": username,
		"密码": password,
	})
})

JSON 数据(最常用,前后端分离)

前端发 application/json,这是目前最主流的方式。

c.ShouldBindJSON(obj any) error

  • 作用:将请求体中的 JSON 数据绑定到结构体指针上
  • 参数 :obj 是结构体指针(必须传指针,否则无法修改原对象)
  • 返回值 :error 类型;若绑定成功返回 nil,失败返回错误信息(如 JSON 格式错误、字段类型不匹配)
go 复制代码
// 1. 先定义结构体(对应 JSON 字段)
type User struct {
	Name string `json:"name"` // 注意 tag 是 json
	Age  int    `json:"age"`
}

r.POST("/register", func(c *gin.Context) {
	var user User

	// 2. 使用 ShouldBindJSON 绑定 JSON 到结构体
	if err := c.ShouldBindJSON(&user); err != nil {
		c.JSON(400, gin.H{"错误": err.Error()})
		return
	}

	c.JSON(200, gin.H{
		"注册成功": user,
	})
})
前端请求示例
javascript 复制代码
fetch('http://127.0.0.1:8080/register', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: "张三", age: 18 })
})

前端可以传多余字段,但后端只绑定自己关心的。


文件上传(单文件 / 多文件)

c.FormFile(key string) (*multipart.FileHeader, error)

  • 作用:获取上传的单个文件

  • 参数 :key 是表单中文件字段的名称

  • 返回值:

    • *multipart.FileHeader:文件对象,包含文件名、大小等信息
    • error:若获取失败返回错误信息

c.SaveUploadedFile(file *multipart.FileHeader, dst string) error

  • 作用:将上传的文件保存到本地指定路径

  • 参数:

    • file:c.FormFile() 获取到的文件对象
    • dst:文件保存的目标路径(如 ./avatar.jpg)
  • 返回值 :error 类型;若保存成功返回 nil,失败返回错误信息

go 复制代码
r.POST("/upload", func(c *gin.Context) {
	// 1. 获取上传的文件
	file, err := c.FormFile("avatar")
	if err != nil {
		c.JSON(400, gin.H{"错误": "上传失败"})
		return
	}

	// 2. 保存到本地
	c.SaveUploadedFile(file, "./"+file.Filename)

	c.JSON(200, gin.H{
		"文件名": file.Filename,
		"大小":   file.Size,
	})
})

统一参数绑定(推荐)

如果不想手动一个个取参数,Gin 支持自动绑定:

c.ShouldBind(obj any) error

  • 作用:根据请求类型自动绑定参数(支持 Query、Form、JSON 等)
  • 参数 :obj 是结构体指针(结构体字段需加对应 tag,如 form:"keyword")
  • 返回值 :error 类型;绑定成功返回 nil,失败返回错误信息
go 复制代码
// 定义结构体,tag 同时支持 query 和 json
type SearchParams struct {
	Keyword string `form:"keyword" json:"keyword"`
	Page    int    `form:"page" json:"page"`
}

r.GET("/search2", func(c *gin.Context) {
	var params SearchParams
	// 自动根据请求类型绑定(Query/Form/JSON)
	if err := c.ShouldBind(&params); err != nil {
		c.JSON(400, gin.H{"错误": err.Error()})
		return
	}
	c.JSON(200, params)
})

一张表总结怎么选

传参方式 适用场景 核心 Gin 方法
路径参数 RESTful API(如 /user/1) c.Param()
Query 参数 GET 请求筛选、分页 c.Query() / c.DefaultQuery()
Form 表单 传统网页表单提交 c.PostForm() / c.DefaultPostForm()
JSON 数据 前后端分离、复杂数据 c.ShouldBindJSON()
文件上传 头像、附件上传 c.FormFile() / c.SaveUploadedFile()

相关推荐
MyFreeIT几秒前
Python Windows Manual
开发语言·python
小小小米粒5 分钟前
不是在构造方法「之前」修饰 Bean、注入;是构造方法跑完之后,才做属性注入,再跑 @PostConstruct。
前端
kiracrimson11 分钟前
STL:List的使用和模拟实现
开发语言·c++·list
小李科技28 分钟前
【性能优化】事件委托:目标定位与 React/Vue 实战
前端·vue.js·react.js·面试·性能优化·前端框架
QianhangQianping35 分钟前
一块大屏的数据在浏览器里怎么变成画面:背景、子屏、前景三层结构
前端·低代码·架构·编辑器·数据可视化·大屏可视化
梦想很大很大1 小时前
让 Codex 自由发挥,给 nvm-desktop 换个 UI
前端·人工智能·设计
北冥you鱼1 小时前
Go 语言 GORM 使用 Preload:从关联查询到嵌套预加载的完整实践
开发语言·jvm·golang
蓝莓味的口香糖1 小时前
【VUE】【CSS】Vue移动端适配主流方案总结
前端·css·vue.js
shennv8881 小时前
接入大模型流式输出后,文字偶尔乱码?问题可能出在前端
前端
csj501 小时前
前端基础之《React(16)—Modal组件封装》
前端·react.js