在Golang中实现多文件上传,核心是利用标准库net/http对multipart/form-data请求的解析能力。服务端通过Request对象的相关方法获取多个文件,再依次读取并保存到磁盘或对象存储中。

前端如何发送多文件
前端需要使用form表单,并将enctype设置为multipart/form-data,input的name相同且添加multiple属性,这样浏览器会把多个文件放在同一个字段里提交。
<form action="http://127.0.0.1:8080/upload" method="post" enctype="multipart/form-data"> <input type="file" name="files" multiple="multiple" /> <input type="submit" value="上传" /> </form>
后端接收与保存文件
在Golang服务端,我们可以先调用ParseMultipartForm限制内存占用,再通过FormFile拿到multipart.FileHeader切片,遍历保存即可。
package main
import (
"io"
"net/http"
"os"
)
func uploadHandler(w http.ResponseWriter, r *http.Request) {
// 限制最大内存为32MB,超出部分写入临时文件
err := r.ParseMultipartForm(32 << 20)
if err != nil {
http.Error(w, "解析表单失败", http.StatusBadRequest)
return
}
// 获取名为files的所有文件
files := r.MultipartForm.File["files"]
for _, fileHeader := range files {
// 打开上传的文件
src, err := fileHeader.Open()
if err != nil {
http.Error(w, "打开文件失败", http.StatusInternalServerError)
return
}
defer src.Close()
// 创建本地目标文件
dst, err := os.Create("./uploads/" + fileHeader.Filename)
if err != nil {
http.Error(w, "创建文件失败", http.StatusInternalServerError)
return
}
defer dst.Close()
// 拷贝内容
if _, err = io.Copy(dst, src); err != nil {
http.Error(w, "保存文件失败", http.StatusInternalServerError)
return
}
}
w.Write([]byte("上传成功"))
}
func main() {
http.HandleFunc("/upload", uploadHandler)
http.ListenAndServe("127.0.0.1:8080", nil)
}
常见注意事项
- 提前创建uploads目录,否则os.Create会报错。
- 生产环境应对文件名做清洗,避免路径遍历攻击。
- 可结合filepath.Base()获取纯文件名。
- 大文件建议分块读写或使用流式上传到云存储。
简单文件名安全处理
使用path/filepath包的Base方法可以防止用户传入../../etc/passwd之类的恶意路径。
import (
"path/filepath"
)
safeName := filepath.Base(fileHeader.Filename)
dst, err := os.Create("./uploads/" + safeName)
小结
通过上述方式,我们能够在Golang中轻松处理多文件上传。核心步骤就是解析multipart表单、遍历文件头、依次拷贝内容。实际项目中再根据业务补充校验与存储策略即可。