Mastering Form Handling and File Uploads with Gin in Go

This guide explains the four common HTTP form content types, demonstrates how to retrieve form data with Gin's PostForm methods, shows step‑by‑step examples for single and multiple file uploads, enforces size and type restrictions, and covers route groups and custom 404 handling in Go.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Mastering Form Handling and File Uploads with Gin in Go

Form Parameters

Form data is sent via POST requests using four typical content types: application/json, application/x-www-form-urlencoded, application/xml, and multipart/form-data. Gin's PostForm() method parses x-www-form-urlencoded and multipart/form-data by default.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Form Example</title>
</head>
<body>
    <form action="http://localhost:8080/form" method="post" enctype="application/x-www-form-urlencoded">
        用户名:<input type="text" name="username" placeholder="请输入你的用户名"> <br>
        密码:<input type="password" name="userpassword" placeholder="请输入你的密码"> <br>
        <input type="submit" value="提交">
    </form>
</body>
</html>
package main

import (
    "fmt"
    "net/http"
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    r.POST("/form", func(ctx *gin.Context) {
        types := ctx.DefaultPostForm("type", "post")
        username := ctx.PostForm("username")
        password := ctx.PostForm("userpassword")
        ctx.String(http.StatusOK, fmt.Sprintf("username:%s,password:%s,type:%s", username, password, types))
    })
    r.Run()
}

File Upload

The multipart/form-data format is used for uploading files. Gin wraps the native net/http request, exposing file handling through the context.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Upload</title>
</head>
<body>
    <form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">
        上传文件: <input type="file" name="file">
        <input type="submit" value="提交">
    </form>
</body>
</html>
package main

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

func main() {
    r := gin.Default()
    // Limit upload size to 8 MB (default is 32 MB)
    r.MaxMultipartMemory = 8 << 20
    r.POST("/upload", func(ctx *gin.Context) {
        file, err := ctx.FormFile("file")
        if err != nil {
            ctx.String(500, "上传图片出错")
            return
        }
        // Save the uploaded file
        ctx.SaveUploadedFile(file, file.Filename)
        ctx.String(http.StatusOK, file.Filename)
    })
    r.Run()
}

Restrict Size and Type

package main

import (
    "fmt"
    "log"
    "net/http"
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    r.POST("/upload", func(c *gin.Context) {
        _, headers, err := c.Request.FormFile("file")
        if err != nil {
            log.Printf("Error when try to get file: %v", err)
            return
        }
        // Limit size to 2 MB
        if headers.Size > 1024*1024*2 {
            fmt.Println("文件太大了")
            return
        }
        // Allow only PNG images
        if headers.Header.Get("Content-Type") != "image/png" {
            fmt.Println("只允许上传png图片")
            return
        }
        c.SaveUploadedFile(headers, "./video/"+headers.Filename)
        c.String(http.StatusOK, headers.Filename)
    })
    r.Run()
}

Upload Multiple Files

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
    "fmt"
)

func main() {
    r := gin.Default()
    // Limit form size to 8 MB
    r.MaxMultipartMemory = 8 << 20
    r.POST("/upload", func(c *gin.Context) {
        form, err := c.MultipartForm()
        if err != nil {
            c.String(http.StatusBadRequest, fmt.Sprintf("get err %s", err.Error()))
            return
        }
        files := form.File["files"]
        for _, file := range files {
            if err := c.SaveUploadedFile(file, file.Filename); err != nil {
                c.String(http.StatusBadRequest, fmt.Sprintf("upload err %s", err.Error()))
                return
            }
        }
        c.String(200, fmt.Sprintf("upload ok %d files", len(files)))
    })
    r.Run(":8000")
}

Route Groups

Route groups help organize URLs with common prefixes.

package main

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

func login(ctx *gin.Context) {
    name := ctx.DefaultQuery("name", "yangchao")
    ctx.String(200, fmt.Sprintf("hello %s
", name))
}

func submit(ctx *gin.Context) {
    name := ctx.DefaultQuery("name", "hcie")
    ctx.String(200, fmt.Sprintf("hello %s
", name))
}

func main() {
    r := gin.Default()
    v1 := r.Group("/v1")
    {
        v1.GET("/login", login)
        v1.GET("/submit", submit)
    }
    v2 := r.Group("/v2")
    {
        v2.POST("/login", login)
        v2.POST("/submit", submit)
    }
    r.Run()
}

Custom 404 Page

package main

import (
    "fmt"
    "net/http"
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    r.GET("/user", func(ctx *gin.Context) {
        name := ctx.DefaultQuery("name", "yangchao")
        ctx.String(http.StatusOK, fmt.Sprintf("hello %s", name))
    })
    // Define custom 404 handler
    r.NoRoute(func(ctx *gin.Context) {
        ctx.String(http.StatusNotFound, "404 no found 1123131")
    })
    r.Run()
}
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Backend Developmentfile uploadForm HandlingGin
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.