基于Go语言实现文件上传服务的示例代码

Written by

in

文章目录
  • 在 Web 开发中,文件上传 是常见需求,例如头像上传、文档存储、图片分享等功能。Go 语言的标准库 net/http 已经内置了对 multipart/form-data 类型的支持,能让我们轻松构建一个文件上传服务。 本文将带你实现一个可运行的文件上传接口,并附带 HTML 表单和 curl 测试方法。
  • 路径:/upload 方法:POST 表单字段: file:上传文件 desc:文件描述(可选) 保存文件到本地 ./uploads 目录 返回 JSON 结果
  • r.ParseMultipartForm(maxMemory):解析 multipart/form-data 表单 r.FormFile("file"):获取上传的文件 io.Copy(dst, src):保存文件到本地 表单字段获取:r.FormValue("desc") 文件权限控制:os.Create() / os.MkdirAll()
  • package main import ( “encoding/json” “fmt” “io” “net/http” “os” “path/filepath” ) type UploadResponse struct { Filename string `json:”filename”` Size int64 `json:”size”` Desc string `json:”desc”` Status string `json:”status”` } func uploadHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, “Method Not Allowed”, http.StatusMethodNotAllowed) return } // 解析上传表单(maxMemory 5MB,超过部分存临时文件) err := r.ParseMultipartForm(5 << 20) if err != nil { http.Error(w, “Error parsing form: “+err.Error(), http.StatusBadRequest) return } // 获取表单字段 desc := r.FormValue(“desc”) // 获取文件 file, handler, err := r.FormFile(“file”) if err != nil { http.Error(w, “Error retrieving file: “+err.Error(), http.StatusBadRequest) return } defer file.Close() // 确保保存目录存在 os.MkdirAll(“./uploads”, os.ModePerm) // 保存文件 filePath := filepath.Join(“uploads”, handler.Filename) dst, err := os.Create(filePath) if err != nil { http.Error(w, “Error saving file: “+err.Error(), http.StatusInternalServerError) return } defer dst.Close() size, err := io.Copy(dst, file) if err != nil { http.Error(w, “Error writing file: “+err.Error(), http.StatusInternalServerError) return } // 返回 JSON 响应 w.Header().Set(“Content-Type”, “application/json”) json.NewEncoder(w).Encode(UploadResponse{ Filename: handler.Filename, Size: size, Desc: desc, Status: “success”, }) } func main() { http.HandleFunc(“/upload”, uploadHandler) fmt.Println(“文件上传服务已启动:http://localhost:8080/upload”) http.ListenAndServe(“:8080”, nil) }
  • 成功上传后返回: { “filename”: “test.png”, “size”: 15324, “desc”: “测试图片”, “status”: “success” } 文件会保存在 ./uploads/test.png。
  • 上传限制: 通过 r.ParseMultipartForm(maxMemory) 控制内存占用,超过部分会写入临时文件。 安全性: 校验文件类型(避免执行恶意文件) 生成唯一文件名(避免覆盖) 设置合理的文件大小限制(可用 http.MaxBytesReader) 跨域请求: 如果前端与后端不在同一域名,需要设置 Access-Control-Allow-Origin 等 CORS 头。
  • 上传时自动生成文件唯一 ID(防止文件名冲突) 返回文件访问 URL 将文件上传到云存储(如 AWS S3、阿里云 OSS) 支持多文件同时上传(r.MultipartForm.File["file"]) 到此这篇关于基于Go语言实现文件上传服务的示例代码的文章就介绍到这了,更多相关Go文件上传服务内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: Go+Gin实现安全多文件上传功能 基于Go语言实现高性能文件上传下载系统 Go通过goroutine实现多协程文件上传的基本流程 Golang使用Gin实现文件上传的示例代码 Golang如何将上传的文件压缩成zip(小案例)
  • 目录
    • 引言
    • 一、目标功能
    • 二、核心知识点
    • 三、完整代码
    • 四、测试方法
      • 1. HTML 表单测试
      • 2. curl 命令测试
    • 五、运行效果
      • 六、注意事项
        • 七、进阶扩展

          在 Web 开发中,文件上传 是常见需求,例如头像上传、文档存储、图片分享等功能。Go 语言的标准库 net/http 已经内置了对 multipart/form-data 类型的支持,能让我们轻松构建一个文件上传服务。

          本文将带你实现一个可运行的文件上传接口,并附带 HTML 表单和 curl 测试方法。

          路径:/upload

          方法:POST

          表单字段:

          • file:上传文件
          • desc:文件描述(可选)

          保存文件到本地 ./uploads 目录

          返回 JSON 结果

          • r.ParseMultipartForm(maxMemory):解析 multipart/form-data 表单
          • r.FormFile("file"):获取上传的文件
          • io.Copy(dst, src):保存文件到本地
          • 表单字段获取:r.FormValue("desc")
          • 文件权限控制:os.Create() / os.MkdirAll()

          package main
          
          import (
              "encoding/json"
              "fmt"
              "io"
              "net/http"
              "os"
              "path/filepath"
          )
          
          type UploadResponse struct {
              Filename string `json:"filename"`
              Size     int64  `json:"size"`
              Desc     string `json:"desc"`
              Status   string `json:"status"`
          }
          
          func uploadHandler(w http.ResponseWriter, r *http.Request) {
              if r.Method != http.MethodPost {
                  http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
                  return
              }
          
              // 解析上传表单(maxMemory 5MB,超过部分存临时文件)
              err := r.ParseMultipartForm(5 << 20)
              if err != nil {
                  http.Error(w, "Error parsing form: "+err.Error(), http.StatusBadRequest)
                  return
              }
          
              // 获取表单字段
              desc := r.FormValue("desc")
          
              // 获取文件
              file, handler, err := r.FormFile("file")
              if err != nil {
                  http.Error(w, "Error retrieving file: "+err.Error(), http.StatusBadRequest)
                  return
              }
              defer file.Close()
          
              // 确保保存目录存在
              os.MkdirAll("./uploads", os.ModePerm)
          
              // 保存文件
              filePath := filepath.Join("uploads", handler.Filename)
              dst, err := os.Create(filePath)
              if err != nil {
                  http.Error(w, "Error saving file: "+err.Error(), http.StatusInternalServerError)
                  return
              }
              defer dst.Close()
          
              size, err := io.Copy(dst, file)
              if err != nil {
                  http.Error(w, "Error writing file: "+err.Error(), http.StatusInternalServerError)
                  return
              }
          
              // 返回 JSON 响应
              w.Header().Set("Content-Type", "application/json")
              json.NewEncoder(w).Encode(UploadResponse{
                  Filename: handler.Filename,
                  Size:     size,
                  Desc:     desc,
                  Status:   "success",
              })
          }
          
          func main() {
              http.HandleFunc("/upload", uploadHandler)
          
              fmt.Println("文件上传服务已启动:http://localhost:8080/upload")
              http.ListenAndServe(":8080", nil)
          }
          

          保存为 upload.html

          <!DOCTYPE html>
          <html>
          <body>
          <h2>文件上传测试</h2>
          <form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">
            文件描述: <input type="text" name="desc">
          
          
            选择文件: <input type="file" name="file">
          
          
            <input type="submit" value="上传">
          </form>
          </body>
          </html>
          

          打开浏览器选择文件并提交。

          curl -X POST http://localhost:8080/upload 
               -F "desc=测试图片" 
               -F "file=@test.png"
          

          成功上传后返回:

          {
            "filename": "test.png",
            "size": 15324,
            "desc": "测试图片",
            "status": "success"
          }
          

          文件会保存在 ./uploads/test.png

          上传限制: 通过 r.ParseMultipartForm(maxMemory) 控制内存占用,超过部分会写入临时文件。

          安全性

          • 校验文件类型(避免执行恶意文件)
          • 生成唯一文件名(避免覆盖)
          • 设置合理的文件大小限制(可用 http.MaxBytesReader

          跨域请求: 如果前端与后端不在同一域名,需要设置 Access-Control-Allow-Origin 等 CORS 头。

          • 上传时自动生成文件唯一 ID(防止文件名冲突)
          • 返回文件访问 URL
          • 将文件上传到云存储(如 AWS S3、阿里云 OSS)
          • 支持多文件同时上传(r.MultipartForm.File["file"]

          到此这篇关于基于Go语言实现文件上传服务的示例代码的文章就介绍到这了,更多相关Go文件上传服务内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

          您可能感兴趣的文章:

          • Go+Gin实现安全多文件上传功能
          • 基于Go语言实现高性能文件上传下载系统
          • Go通过goroutine实现多协程文件上传的基本流程
          • Golang使用Gin实现文件上传的示例代码
          • Golang如何将上传的文件压缩成zip(小案例)

          站内搜索