请求处理 #
一、请求参数 #
1.1 路径参数 #
go
// 必需参数
app.Get("/users/:id", func(c *fiber.Ctx) error {
id := c.Params("id")
return c.SendString("User ID: " + id)
})
// 多个参数
app.Get("/users/:userId/posts/:postId", func(c *fiber.Ctx) error {
userId := c.Params("userId")
postId := c.Params("postId")
return c.JSON(fiber.Map{
"user_id": userId,
"post_id": postId,
})
})
// 可选参数
app.Get("/search/:keyword?", func(c *fiber.Ctx) error {
keyword := c.Params("keyword", "default")
return c.SendString("Keyword: " + keyword)
})
// 整数参数
app.Get("/page/:num", func(c *fiber.Ctx) error {
num := c.ParamsInt("num", 1)
return c.SendString("Page: " + strconv.Itoa(num))
})
// 通配符
app.Get("/files/*", func(c *fiber.Ctx) error {
path := c.Params("*")
return c.SendString("Path: " + path)
})
1.2 查询参数 #
go
app.Get("/search", func(c *fiber.Ctx) error {
// 字符串参数
q := c.Query("q")
page := c.Query("page", "1")
// 整数参数
limit := c.QueryInt("limit", 10)
offset := c.QueryInt("offset", 0)
// 布尔参数
active := c.QueryBool("active", false)
// 浮点参数
price := c.QueryFloat("price", 0.0)
// 所有参数
all := c.Queries()
return c.JSON(fiber.Map{
"q": q,
"page": page,
"limit": limit,
"active": active,
"price": price,
"all": all,
})
})
1.3 解析查询到结构体 #
go
type SearchQuery struct {
Q string `query:"q"`
Page int `query:"page"`
Limit int `query:"limit"`
Sort string `query:"sort"`
Order string `query:"order"`
}
app.Get("/users", func(c *fiber.Ctx) error {
var query SearchQuery
query.Page = 1
query.Limit = 10
query.Sort = "id"
query.Order = "asc"
if err := c.QueryParser(&query); err != nil {
return c.Status(400).JSON(fiber.Map{
"error": "Invalid query parameters",
})
}
return c.JSON(query)
})
二、请求体解析 #
2.1 JSON解析 #
go
type User struct {
Name string `json:"name"`
Email string `json:"email"`
Age int `json:"age"`
}
app.Post("/users", func(c *fiber.Ctx) error {
var user User
if err := c.BodyParser(&user); err != nil {
return c.Status(400).JSON(fiber.Map{
"error": "Invalid JSON",
})
}
return c.JSON(user)
})
2.2 表单解析 #
go
type LoginForm struct {
Username string `form:"username"`
Password string `form:"password"`
Remember bool `form:"remember"`
}
app.Post("/login", func(c *fiber.Ctx) error {
var form LoginForm
if err := c.BodyParser(&form); err != nil {
return c.Status(400).JSON(fiber.Map{
"error": "Invalid form data",
})
}
return c.JSON(form)
})
2.3 多部分表单 #
go
app.Post("/upload", func(c *fiber.Ctx) error {
// 获取表单字段
name := c.FormValue("name")
description := c.FormValue("description")
// 获取文件
file, err := c.FormFile("file")
if err != nil {
return c.Status(400).JSON(fiber.Map{
"error": "File is required",
})
}
// 保存文件
if err := c.SaveFile(file, "./uploads/"+file.Filename); err != nil {
return c.Status(500).JSON(fiber.Map{
"error": "Failed to save file",
})
}
return c.JSON(fiber.Map{
"name": name,
"description": description,
"filename": file.Filename,
"size": file.Size,
})
})
2.4 原始Body #
go
app.Post("/raw", func(c *fiber.Ctx) error {
// 字节切片
body := c.Body()
// 字符串
bodyStr := c.BodyString()
return c.Send(body)
})
2.5 XML解析 #
go
type UserXML struct {
XMLName xml.Name `xml:"user"`
Name string `xml:"name"`
Email string `xml:"email"`
}
app.Post("/xml", func(c *fiber.Ctx) error {
var user UserXML
if err := xml.Unmarshal(c.Body(), &user); err != nil {
return c.Status(400).JSON(fiber.Map{
"error": "Invalid XML",
})
}
return c.JSON(user)
})
三、请求头 #
3.1 获取请求头 #
go
app.Get("/headers", func(c *fiber.Ctx) error {
// 单个请求头
contentType := c.Get("Content-Type")
authorization := c.Get("Authorization")
userAgent := c.Get("User-Agent")
// 快捷方法
host := c.Hostname()
accept := c.Get("Accept")
return c.JSON(fiber.Map{
"content-type": contentType,
"authorization": authorization,
"user-agent": userAgent,
"host": host,
"accept": accept,
})
})
3.2 遍历所有请求头 #
go
app.Get("/all-headers", func(c *fiber.Ctx) error {
headers := make(map[string]string)
c.Request().Header.VisitAll(func(key, value []byte) {
headers[string(key)] = string(value)
})
return c.JSON(headers)
})
四、文件上传 #
4.1 单文件上传 #
go
app.Post("/upload", func(c *fiber.Ctx) error {
// 获取文件
file, err := c.FormFile("file")
if err != nil {
return c.Status(400).JSON(fiber.Map{
"error": "File is required",
})
}
// 文件信息
fmt.Println("Filename:", file.Filename)
fmt.Println("Size:", file.Size)
fmt.Println("Header:", file.Header)
// 保存文件
err = c.SaveFile(file, "./uploads/"+file.Filename)
if err != nil {
return c.Status(500).JSON(fiber.Map{
"error": "Failed to save file",
})
}
return c.JSON(fiber.Map{
"message": "File uploaded successfully",
"filename": file.Filename,
"size": file.Size,
})
})
4.2 多文件上传 #
go
app.Post("/uploads", func(c *fiber.Ctx) error {
// 解析多部分表单
form, err := c.MultipartForm()
if err != nil {
return c.Status(400).JSON(fiber.Map{
"error": "Invalid multipart form",
})
}
// 获取所有文件
files := form.File["files"]
var results []fiber.Map
for _, file := range files {
// 保存文件
err := c.SaveFile(file, "./uploads/"+file.Filename)
if err != nil {
results = append(results, fiber.Map{
"filename": file.Filename,
"error": err.Error(),
})
continue
}
results = append(results, fiber.Map{
"filename": file.Filename,
"size": file.Size,
"status": "uploaded",
})
}
return c.JSON(fiber.Map{
"total": len(files),
"files": results,
})
})
4.3 文件类型验证 #
go
func validateFileType(file *multipart.FileHeader) bool {
allowedTypes := map[string]bool{
"image/jpeg": true,
"image/png": true,
"image/gif": true,
"application/pdf": true,
}
// 获取文件内容类型
f, err := file.Open()
if err != nil {
return false
}
defer f.Close()
buffer := make([]byte, 512)
_, err = f.Read(buffer)
if err != nil {
return false
}
contentType := http.DetectContentType(buffer)
return allowedTypes[contentType]
}
app.Post("/upload-safe", func(c *fiber.Ctx) error {
file, err := c.FormFile("file")
if err != nil {
return c.Status(400).JSON(fiber.Map{
"error": "File is required",
})
}
if !validateFileType(file) {
return c.Status(400).JSON(fiber.Map{
"error": "Invalid file type",
})
}
// 保存文件...
return c.JSON(fiber.Map{"message": "OK"})
})
五、Cookie处理 #
5.1 获取Cookie #
go
app.Get("/get-cookie", func(c *fiber.Ctx) error {
session := c.Cookies("session")
token := c.Cookies("token", "default")
return c.JSON(fiber.Map{
"session": session,
"token": token,
})
})
5.2 获取所有Cookie #
go
app.Get("/all-cookies", func(c *fiber.Ctx) error {
cookies := make(map[string]string)
c.Request().Header.VisitAllCookie(func(key, value []byte) {
cookies[string(key)] = string(value)
})
return c.JSON(cookies)
})
六、请求信息 #
6.1 客户端信息 #
go
app.Get("/client-info", func(c *fiber.Ctx) error {
return c.JSON(fiber.Map{
"ip": c.IP(),
"ips": c.IPs(),
"hostname": c.Hostname(),
"protocol": c.Protocol(),
"secure": c.Secure(),
"user_agent": c.Get("User-Agent"),
"referer": c.Get("Referer"),
})
})
6.2 请求方法判断 #
go
app.All("/check", func(c *fiber.Ctx) error {
method := c.Method()
switch method {
case fiber.MethodGet:
return c.SendString("GET request")
case fiber.MethodPost:
return c.SendString("POST request")
case fiber.MethodPut:
return c.SendString("PUT request")
case fiber.MethodDelete:
return c.SendString("DELETE request")
default:
return c.Status(405).SendString("Method not allowed")
}
})
6.3 Content-Type判断 #
go
app.Post("/content", func(c *fiber.Ctx) error {
contentType := c.Get("Content-Type")
switch {
case strings.Contains(contentType, "application/json"):
// 处理JSON
var data map[string]interface{}
c.BodyParser(&data)
return c.JSON(data)
case strings.Contains(contentType, "application/x-www-form-urlencoded"):
// 处理表单
name := c.FormValue("name")
return c.SendString("Form: " + name)
case strings.Contains(contentType, "multipart/form-data"):
// 处理文件上传
file, _ := c.FormFile("file")
return c.SendString("File: " + file.Filename)
default:
return c.Status(400).SendString("Unsupported content type")
}
})
七、综合示例 #
7.1 完整请求处理 #
go
package main
import (
"github.com/gofiber/fiber/v2"
)
type CreateUserRequest struct {
Name string `json:"name" validate:"required"`
Email string `json:"email" validate:"required,email"`
Password string `json:"password" validate:"required,min=6"`
Age int `json:"age" validate:"min=0,max=150"`
}
type UserResponse struct {
ID string `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
Age int `json:"age"`
CreateAt string `json:"created_at"`
}
func main() {
app := fiber.New()
app.Post("/users", func(c *fiber.Ctx) error {
// 解析请求体
var req CreateUserRequest
if err := c.BodyParser(&req); err != nil {
return c.Status(400).JSON(fiber.Map{
"error": "Invalid request body",
})
}
// 验证请求
if req.Name == "" {
return c.Status(400).JSON(fiber.Map{
"error": "Name is required",
})
}
if req.Email == "" {
return c.Status(400).JSON(fiber.Map{
"error": "Email is required",
})
}
// 创建用户
user := UserResponse{
ID: "1",
Name: req.Name,
Email: req.Email,
Age: req.Age,
CreateAt: "2024-01-01T00:00:00Z",
}
// 返回响应
return c.Status(201).JSON(user)
})
app.Listen(":3000")
}
八、总结 #
8.1 请求处理方法汇总 #
| 方法 | 用途 |
|---|---|
| c.Params() | 路径参数 |
| c.Query() | 查询参数 |
| c.FormValue() | 表单参数 |
| c.BodyParser() | 解析请求体 |
| c.Get() | 请求头 |
| c.Cookies() | Cookie |
| c.FormFile() | 上传文件 |
| c.IP() | 客户端IP |
8.2 下一步 #
现在你已经掌握了请求处理,接下来让我们学习 响应处理,了解如何返回各种类型的响应!
最后更新:2026-03-28