Gin 如何实现单个文件上传

Gin 框架中的文件上传其实引用的是 Go 标准库 net/http 的文件上传方式。不过呢,Gin 自己也封装了一个 gin.Context.SaveUploadedFile() 用于保存文件

file, err := c.FormFile("file")  // 获取上传的文件
// 处理 err
filename := filepath.Base(file.Filename)    // 获取文件名
err = c.SaveUploadedFile(file, filename)    // 保存文件
// 处理 error

更多内容可以参考 Github issue #774example code.

注意

file.Filename 是不可信的

file.Filename 并不总是存在且有正确的值。而且存在上传漏洞,不要盲目使用。 如果要使用原始的文件名,那么推荐的做法是使用 filepath.Base(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")

        // 单文件
        file, err := c.FormFile("file")
        if err != nil {
            c.String(http.StatusBadRequest, "get form err: %s", err.Error())
            return
        }

        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, "File %s uploaded successfully with fields name=%s and email=%s.", file.Filename, name, email)
    })
    router.Run(":8080")
}

public/index.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Single file upload</title>
</head>
<body>
<h1>Upload single file 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="file"><br><br>
    <input type="submit" value="Submit">
</form>
</body>

Gin 服务运行后,你可以使用下面的 cURL 命令来测试 How to curl:

curl -X POST http://localhost:8080/upload \
  -F "file=@/Users/appleboy/test.zip" \
  -H "Content-Type: multipart/form-data"

有关 Content-Disposition 的内容,你可以阅读 Content-Disposition on MDNGithub issue #1693

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.