go 文件上传需先调用 r.ParseMultipartForm(32

在 Go 语言中实现文件上传功能,核心是使用 http.Request 的 ParseMultipartForm 和 FormFile 方法解析客户端提交的 multipart/form-data 表单,并将文件流保存到服务器本地磁盘。
接收并解析上传的文件
Go 标准库 net/http 原生支持 multipart 文件上传。需先调用 r.ParseMultipartForm 初始化表单解析(指定最大内存缓存大小),再通过 r.FormFile 获取文件句柄和头信息。
ParseMultipartForm(32 表示最多将 32MB 以内的文件暂存在内存,超过部分写入临时磁盘文件-
FormFile("file")中"file"需与 HTML 表单中的name属性一致 - 返回值为
multipart.File(可读的文件流)和*multipart.FileHeader(含原始文件名、大小、MIME 类型等)
安全地保存文件到服务器磁盘
直接使用客户端传来的原始文件名保存存在路径遍历(如 ../../etc/passwd)或覆盖风险,必须做校验和清洗。
- 用
path.Base(header.Filename)提取纯文件名,剥离路径部分 - 建议生成唯一文件名(如结合
uuid.New().String()或时间戳 + 随机数),避免重名和猜测 - 明确指定保存目录(如
"./uploads/"),提前创建目录并检查权限:os.MkdirAll(uploadDir, 0755) - 打开目标文件时使用
os.O_CREATE | os.O_WRONLY | os.O_EXCL模式防止覆盖已有文件
完整可运行示例
以下是一个最小可用的上传服务端代码片段:
小生淘宝客程序打折程序
0
淘宝客打折系统,集成了jssdk模块,增加了seo优化功能,更有利于搜索引擎收录 1程序上传到服务器空间 2开启服务器 3打开安装地址:http://您的域名/install.php 4如果不能安装请确保数据库里的表全部删除 5进入后台地址:http://您的域名/main.php 默认用户名和密码都是admin 6测试数据时可以导入 test文件夹里的test.sql文件 到数据库,或者
0 立即学习“go语言免费学习笔记(深入)”;
package main import ( "io" "net/http" "os" "path" "path/filepath" ) func uploadHandler(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { http.ServeFile(w, r, "upload.html") // 提供上传页面 return } err := r.ParseMultipartForm(32 << 20) if err != nil { http.Error(w, "解析表单失败: "+err.Error(), http.StatusBadRequest) return } file, header, err := r.FormFile("file") if err != nil { http.Error(w, "获取文件失败: "+err.Error(), http.StatusBadRequest) return } defer file.Close() uploadDir := "./uploads" os.MkdirAll(uploadDir, 0755) // 安全处理文件名 safeName := filepath.Base(header.Filename) dstPath := filepath.Join(uploadDir, safeName) dst, err := os.OpenFile(dstPath, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0644) if err != nil { http.Error(w, "无法创建目标文件: "+err.Error(), http.StatusInternalServerError) return } defer dst.Close() if _, err := io.Copy(dst, file); err != nil { http.Error(w, "保存文件失败: "+err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) w.Write([]byte("上传成功:" + safeName)) } func main() { http.HandleFunc("/upload", uploadHandler) http.ListenAndServe(":8080", nil) }
配套的 upload.html 示例:
<form action="/upload" method="post" enctype="multipart/form-data"> <input type="file" name="file" required> <button type="submit">上传</button> </form>
补充建议
生产环境还需考虑更多细节:
- 限制单个文件大小(
ParseMultipartForm参数)和总请求体大小(可在中间件中用http.MaxBytesReader包裹r.Body) - 校验文件 MIME 类型或魔数(
header.Header.Get("Content-Type")可被伪造,需读取前几字节验证) - 对图片等文件可额外调用
image.DecodeConfig验证是否真实可解析 - 上传完成后可返回 JSON 响应(如
{"success": true, "url": "/uploads/xxx.jpg"}),便于前端进一步处理