跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

如何在Golang中实现文件上传功能_保存客户端上传文件到服务器

Go 文件上传需先调用 r.ParseMultipartForm(32 << 20) 解析 multipart 表单,再用 r.FormFile 获取文件句柄与头信息,最后保存至磁盘。 在 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
模式防止覆盖已有文件 完整可运行示例 以下是一个最小可用的上传服务端代码片段: Python3.6标准库参考手册(PDF版) Python3.6标准库参考手册(PDF版) 下载 立即学习 “ 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
示例:
补充建议 生产环境还需考虑更多细节: 限制单个文件大小(
ParseMultipartForm
参数)和总请求体大小(可在中间件中用
http.MaxBytesReader
包裹
r.Body
) 校验文件 MIME 类型或魔数(
header.Header.Get("Content-Type")
可被伪造,需读取前几字节验证) 对图片等文件可额外调用
image.DecodeConfig
验证是否真实可解析 上传完成后可返回 JSON 响应(如
{"success": true, "url": "https://www.vqhf.com/uploads/xxx.jpg"}
),便于前端进一步处理

相关文章