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

 更新时间:2025年08月11日 08:25:47   作者:程序员爱钓鱼  
在 Web 开发中,文件上传 是常见需求,例如头像上传、文档存储、图片分享等功能,Go 语言的标准库 net/http 已经内置了对 multipart/form-data 类型的支持,能让我们轻松构建一个文件上传服务,本文将带你实现一个可运行的文件上传接口,需要的朋友可以参考下

引言

在 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)
}

四、测试方法

1. HTML 表单测试

保存为 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>

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

2. curl 命令测试

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语言库系列之dotsql详解

    Go语言库系列之dotsql详解

    这篇文章主要介绍了Go语言库系列之dotsql的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • golang格式化输出函数printf、sprintf、fprintf解读

    golang格式化输出函数printf、sprintf、fprintf解读

    这篇文章主要介绍了golang格式化输出函数printf、sprintf、fprintf,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-07-07
  • Go调度器学习之系统调用详解

    Go调度器学习之系统调用详解

    这篇文章肿,将以一个简单的文件打开的系统调用,来分析一下Go调度器在系统调用时做了什么。文中的示例代码讲解详细,需要的可以参考一下
    2023-04-04
  • 从Context到go设计理念轻松上手教程

    从Context到go设计理念轻松上手教程

    这篇文章主要为大家介绍了从Context到go设计理念轻松上手教程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • 一文带你了解Go中跟踪函数调用链的实现

    一文带你了解Go中跟踪函数调用链的实现

    这篇文章主要为大家详细介绍了go如何实现一个自动注入跟踪代码,并输出有层次感的函数调用链跟踪命令行工具,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-11-11
  • 深度解密 Go 语言中的 sync.map

    深度解密 Go 语言中的 sync.map

    这篇文章主要介绍了深度解密 Go 语言中的 sync.map,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • Go语言异常处理案例解析

    Go语言异常处理案例解析

    这篇文章主要介绍了Go语言异常处理案例解析,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • Golang有类型常量和无类型常量的区别

    Golang有类型常量和无类型常量的区别

    本文主要介绍了Golang有类型常量和无类型常量的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Go语言学习之goroutine详解

    Go语言学习之goroutine详解

    Goroutine是建立在线程之上的轻量级的抽象。它允许我们以非常低的代价在同一个地址空间中并行地执行多个函数或者方法,这篇文章主要介绍了Go语言学习之goroutine的相关知识,需要的朋友可以参考下
    2020-02-02
  • Golang官方限流器time/rate的使用与实现详解

    Golang官方限流器time/rate的使用与实现详解

    限流器是后台服务中十分重要的组件,在实际的业务场景中使用居多。time/rate 包基于令牌桶算法实现限流,本文主要为大家介绍了time/rate的使用与实现,需要的可以参考一下
    2023-04-04

最新评论