Go图片上传与展示需处理三件事:接收HTTP文件上传、安全保存(防路径遍历/类型伪造)、正确提供静态访问;用net/http解析multipart/form-data,调用r.ParseMultipartForm触发解析,再从r.MultipartForm.File获取文件头。
在 Go 中构建图片上传与展示应用,核心是处理好三件事:接收 HTTP 文件上传、安全地保存文件(避免路径遍历、类型伪造等)、再通过 HTTP 正确提供静态访问。不需要框架也能干净实现,关键是理清职责边界。
Go 标准库 net/http 原生支持 multipart/form-data。关键不是读整个 body,而是用 r.ParseMultipartForm 触发解析,再从 r.MultipartForm.File 获取文件头信息:
r.ParseMultipartForm(32 设置内存上限(如 32MB),超限会自动流式写入临时磁盘
file, header, err := r.FormFile("image") 获取上传的文件句柄和原始文件名header.Header.Get("Content-Type"),但不能全信——需结合魔数校验(见下一条)直接用用户传的文件名或 Content-Type 保存极不安全。应做三层防护:
FF D8 FF)、PNG(89 50 4E 47)、GIF(47 49 46 38)等真实签名,拒绝非图文件uuid.New().String() + filepath.Ext(header.Filename),彻底脱离原始名称./uploads/ 这类非 public 目录;对外提供服务时,用独立的静态路由(如 /images/)映射过去,不暴露真实路径不要手写 http.ServeFile 处理每个请求。推荐两种方式:
http.StripPrefix + http.FileServer 挂载子路径:http.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir("./uploads/"))))
w.Header().Set("Content-Type", "image/jpeg") 和 "Cache-Control: pu
blic, max-age=86400"
./uploads/ 目录存在且进程有读写权限;生产环境建议用绝对路径或配置项指定后端再健壮,前端也得配好才能上传成功:
enctype="multipart/form-data",否则文件不会被发送,限制选择范围fetch 或 FormData 更可控,例如:const fd = new FormData(); fd.append("image", file); fetch("/upload", { method: "POST", body: fd });
,路径与后端静态服务路径一致即可