当前位置: 首页 > news >正文

Go语言实战案例:文件上传服务

在 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 mainimport ("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"><br><br>选择文件: <input type="file" name="file"><br><br><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


六、注意事项

  1. 1. 上传限制
    通过 r.ParseMultipartForm(maxMemory) 控制内存占用,超过部分会写入临时文件。
  2. 2. 安全性
    • • 校验文件类型(避免执行恶意文件)
    • • 生成唯一文件名(避免覆盖)
    • • 设置合理的文件大小限制(可用 http.MaxBytesReader
  3. 3. 跨域请求
    如果前端与后端不在同一域名,需要设置 Access-Control-Allow-Origin 等 CORS 头。

七、进阶扩展

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

http://www.xdnf.cn/news/1268929.html

相关文章:

  • 分析报告:基于字节连续匹配技术的KV缓存共享实施可能性及其扩展
  • Leetcode——556. 下一个更大元素 III
  • Kotlin反射详解
  • Docker大全
  • Linux之shell脚本篇(四)
  • 简单聊聊PowerShell
  • 使用 Prometheus+cAdvisor 监控 Docker 容器指标
  • 算法_python_学习记录_01
  • Docker多阶段构建及适用镜像推荐
  • 软件工程总体设计:从抽象到具体的系统构建之道
  • WinForm 复合控件(用户控件):创建与使用指南
  • 10. 怎么实现深拷贝?
  • 【n8n】学习n8n【10】:Github的项目n8n-workflows:本地安装2,053 个 n8n 工作流程集合:随时看随时抄/学习~
  • 嵌入式 - Linux软件编程
  • 基于 RAUC 的 Jetson OTA 升级全攻略
  • 【文献阅读】我国生态问题鉴定与国土空间生态保护修复方向
  • 本地部署接入 whisper + ollama qwen3:14b 总结字幕
  • 【R语言】单细胞数据整合质量评估(3)
  • 初学python的我开始Leetcode题15-2
  • 【Python 工具人快餐 · 第 2 份】
  • TensorFlow深度学习实战(29)——强化学习(Reinforcement learning,RL)
  • Android 开发问题:The specified child already has a parent.
  • Visual Studio Code (v1.103) 中 GitHub Copilot 最新更新!
  • LLM表征的提取方式
  • n8n飞书webhook配置(飞书机器人、飞书bot、feishu bot)Crypto节点、js timestamp代码、Crypto node
  • 电机控制器母线电压采样芯片有哪些
  • 机器学习——模型的简单优化
  • 如何判断一个数是 2 的幂 / 3 的幂 / 4 的幂 / n 的幂 位运算 总结和思考 每日一题 C++的题解与思路
  • 机器翻译:需要了解的数学基础详解
  • 客服Agent革命:智能客服系统的技术实现与效果评估