Gin 如何实现多个文件上传
一次上传多个文件和一次传单个文件的逻辑类似。区别就是两点
Gin 框架中的文件上传其实引用的是 Go 标准库 net/http
的文件上传方式。不过呢,Gin 自己也封装了一个 gin.Context.SaveUploadedFile()
用于保存文件
1. 使用 name 数组获取多个文件
form, _ := c.MultipartForm() files := form.File["upload[]"]
2. 使用 for range
循环文件并保存/处理
for _, file := range files { filename := filepath.Base(file.Filename) c.SaveUploadedFile(file, filename) }
示例
目录结构如图
├── go.mod ├── go.sum ├── main.go ├── public └── index.html
main.go
package main import ( "net/http" "path/filepath" "github.com/gin-gonic/gin" ) func main() { router := gin.Default() // 为 multipart forms 设置较低的内存限制 (默认是 32 MiB) router.MaxMultipartMemory = 8 << 20 // 8 MiB router.Static("/", "./public") router.POST("/upload", func(c *gin.Context) { name := c.PostForm("name") email := c.PostForm("email") // Multipart 表单 form, err := c.MultipartForm() if err != nil { c.String(http.StatusBadRequest, "get form err: %s", err.Error()) return } files := form.File["files"] for _, file := range files { filename := filepath.Base(file.Filename) if err := c.SaveUploadedFile(file, filename); err != nil { c.String(http.StatusBadRequest, "upload file err: %s", err.Error()) return } } c.String(http.StatusOK, "Uploaded successfully %d files with fields name=%s and email=%s.", len(files), name, email) }) router.Run(":8080") }
public/index.html
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Multiple file upload</title> </head> <body> <h1>Upload multiple files with fields</h1> <form action="/upload" method="post" enctype="multipart/form-data"> Name: <input type="text" name="name"><br> Email: <input type="email" name="email"><br> Files: <input type="file" name="files" multiple><br><br> <input type="submit" value="Submit"> </form> </body> </html>
Gin 服务运行后,你可以使用下面的 cURL 命令来测试
curl -X POST http://localhost:8080/upload \ -F "upload[]=@/Users/appleboy/test1.zip" \ -F "upload[]=@/Users/appleboy/test2.zip" \ -H "Content-Type: multipart/form-data"