处理请求时,经常需要获取各种请求信息。Gin 的 Context 提供了丰富的方法来获取这些信息。
r.Any("/method", func(c *gin.Context) {
method := c.Request.Method
if c.Request.Method == "GET" {
}
if c.Request.Method == "POST" {
}
c.String(200, "Method: %s", method)
})
r.GET("/path/*action", func(c *gin.Context) {
path := c.Request.URL.Path
fullPath := c.FullPath()
action := c.Param("action")
c.JSON(200, gin.H{
"path": path,
"fullPath": fullPath,
"action": action,
})
})
r.GET("/ip", func(c *gin.Context) {
ip := c.ClientIP()
c.String(200, "Your IP: %s", ip)
})
ClientIP() 会依次检查:
r.GET("/headers", func(c *gin.Context) {
auth := c.GetHeader("Authorization")
contentType := c.ContentType()
userAgent := c.UserAgent()
referer := c.GetHeader("Referer")
allHeaders := c.Request.Header
c.JSON(200, gin.H{
"authorization": auth,
"contentType": contentType,
"userAgent": userAgent,
"referer": referer,
"all": allHeaders,
})
})
r.GET("/search", func(c *gin.Context) {
q := c.Query("q")
page := c.DefaultQuery("page", "1")
size := c.DefaultQuery("size", "10")
allQuery := c.Request.URL.Query()
c.JSON(200, gin.H{
"q": q,
"page": page,
"size": size,
"all": allQuery,
})
})
r.POST("/form", func(c *gin.Context) {
username := c.PostForm("username")
password := c.PostForm("password")
remember := c.DefaultPostForm("remember", "false")
c.JSON(200, gin.H{
"username": username,
"password": password,
"remember": remember,
})
})
r.GET("/users/:id", func(c *gin.Context) {
id := c.Param("id")
c.String(200, "User ID: %s", id)
})
r.GET("/files/*filepath", func(c *gin.Context) {
filepath := c.Param("filepath")
c.String(200, "File: %s", filepath)
})
r.POST("/body", func(c *gin.Context) {
body, err := c.GetRawData()
if err != nil {
c.String(400, "Error reading body")
return
}
c.String(200, "Body: %s", string(body))
})
r.POST("/upload", func(c *gin.Context) {
file, err := c.FormFile("file")
if err != nil {
c.String(400, "No file")
return
}
c.JSON(200, gin.H{
"filename": file.Filename,
"size": file.Size,
"header": file.Header,
})
})
r.POST("/check", func(c *gin.Context) {
contentType := c.ContentType()
var result string
switch {
case strings.Contains(contentType, "application/json"):
result = "JSON 请求"
case strings.Contains(contentType, "application/x-www-form-urlencoded"):
result = "表单请求"
case strings.Contains(contentType, "multipart/form-data"):
result = "文件上传请求"
default:
result = "其他类型请求"
}
c.String(200, result)
})
r.GET("/request-info", func(c *gin.Context) {
info := gin.H{
"method": c.Request.Method,
"url": c.Request.URL.String(),
"path": c.Request.URL.Path,
"fullPath": c.FullPath(),
"host": c.Request.Host,
"clientIP": c.ClientIP(),
"contentType": c.ContentType(),
"userAgent": c.UserAgent(),
"referer": c.GetHeader("Referer"),
"contentLength": c.Request.ContentLength,
"headers": c.Request.Header,
"query": c.Request.URL.Query(),
"cookies": c.Request.Cookies(),
"isWebSocket": c.IsWebsocket(),
"scheme": c.Request.URL.Scheme,
}
c.JSON(200, info)
})
type LoginRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
}
r.POST("/login", func(c *gin.Context) {
var req LoginRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
c.JSON(200, gin.H{
"username": req.Username,
})
})
如果需要访问原始的 http.Request:
r.GET("/raw", func(c *gin.Context) {
req := c.Request
req.Method
req.URL
req.Header
req.Body
req.Cookies()
req.Context()
c.String(200, "OK")
})
Gin 提供了丰富的请求信息获取方法,大部分场景下不需要直接访问 c.Request。记住 Query 用于 URL 参数,PostForm 用于表单参数,Param 用于路由参数,GetHeader 用于请求头。