必须提前调用 http.Request.ParseMultipartForm 并设置 MaxMemory,否则 r.MultipartReader() 返回 nil、r.FormFile 报“http: no such file”错误;默认禁用 multipart 解析,参数为内存缓存上限(如 32
http.Request.ParseMultipartForm 必须提前设置 MaxMemory
不调用或忘记设置 ParseMultipartForm,会导致 r.MultipartReader() 返回 nil,r.FormFile 报 http: no such file 错误。这不是文件名写错,而是 Go 默认禁用 multipart 解析。
ParseMultipartForm 参数是最大内存缓存字节数,比如 32 (32MB),超过部分自动流式写入临时磁盘文件
FormFile 或访问 r.MultipartReader() 前调用,顺序错误会静默失败10 足够;大文件上传需配合 io.Copy 流式处理,避免全量加载进内存
r.FormFile 返回的 *multipart.FileHeader 需校验 Size 和 Header
前端可能伪造 Content-Type,仅靠 file.Header.Get("Content-Type") 不可靠;真实 MIME 类型需用 net/http.DetectContentType 检查前 512 字节。
file.Size 是客户端声明大小,可能被篡改,需与实际读取字节数比对file.Filename 提取(注意路径遍历:用 filepath.Base 清洗)strings.HasSuffix(strings.ToLower(filepath.Base(file.Filename)), ".jpg") + DetectContentType 读取开头字节file.Filename 当本地路径用户上传的 Filename 可能含 ../、空字节、Unicode 控制符,直接拼接 os.OpenFile 路径会导致目录穿越或 open 失败。
filepath.Base 截取纯文件名,再生成唯一前缀(如 uuid.New().String())./uploads/,禁止拼接用户输入的任意路径段os.Stat 确认父目录存在,不存在则 os.MkdirAll
func uploadHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
err := r.ParseMultipartForm(32 << 20)
if err != nil {
http.Error(w, "Parse form error: "+err.Error(), http.StatusBadRequest)
return
}
file, header, err := r.FormFile("image")
if err != nil {
http.Error(w, "No image field or parse error", http.StatusBadRequest)
return
}
defer file.Close()
// 校验文件名和类型
filename := filepath.Base(header.Filename)
if filename == "." || filename == "" {
http.Error(w, "Invalid filename", http.StatusBadRequest)
return
}
buf := make([]byte, 512)
_, _ = file.Read(buf)
filetype := http.DetectContentType(buf)
if !strings.HasPrefix(filetype, "image/") {
http.Error(w, "Not an image", http.StatusBadRequest)
return
}
// 重置 reader 到开头(Read 已消耗 buf)
file.Seek(0, 0)
// 生成安全路径
uploadDir := "./uploads"
if _, err := os.Stat(uploadDir); os.IsNotExist(err) {
os.MkdirAll(uploadDir, 0755)
}
safePath := filepath.Join(uploadDir, uuid.New().String()+"_"+filename)
out, err := os.Create(safePath)
if err != nil {
http.Error(w, "Save failed", http.StatusInternalServerError)
return
}
defer out.Close()
if _, err := io.Copy(out, file); err != nil {
http.Error(w, "Write failed", http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{"path": safePath})
}
Golang 上传图片真正的难点不在接收,而在边界控制:内存阈值、类型探测、路径净化、流式写入——这些环节漏掉任何一个,上线后都可能变成安全漏洞或 OOM 崩溃。
# go
# golang
# 字节
# nil
# http
# 流式
# 上传
# 遍历
# 设为
# 而在
# 这不是
# 扩展名
# 不存在
# 任何一个
# 上传图片
相关文章:
大连网站制作公司哪家好一点,大连买房网站哪个好?
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
如何在Golang中指定模块版本_使用go.mod控制版本号
自助网站制作软件,个人如何自助建网站?
武清网站制作公司,天津武清个人营业执照注销查询系统网站?
极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?
建站之星五站合一营销型网站搭建攻略,流量入口全覆盖优化指南
logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?
清单制作人网站有哪些,近日“兴风作浪的姑奶奶”引起很多人的关注这是什么事情?
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
php8.4新语法match怎么用_php8.4match表达式替代switch【方法】
个人网站制作流程图片大全,个人网站如何注销?
如何构建满足综合性能需求的优质建站方案?
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
深圳网站制作培训,深圳哪些招聘网站比较好?
建站之星会员如何解锁更多建站功能?
网站专业制作公司有哪些,做一个公司网站要多少钱?
定制建站平台哪家好?企业官网搭建与快速建站方案推荐
潍坊网站制作公司有哪些,潍坊哪家招聘网站好?
如何通过虚拟主机空间快速建站?
建站主机默认首页配置指南:核心功能与访问路径优化
深入理解Android中的xmlns:tools属性
h5网站制作工具有哪些,h5页面制作工具有哪些?
制作网页的网站有哪些,电脑上怎么做网页?
浅谈Javascript中的Label语句
如何设计高效校园网站?
如何在万网ECS上快速搭建专属网站?
建站之星IIS配置教程:代码生成技巧与站点搭建指南
如何访问已购建站主机并解决登录问题?
如何正确下载安装西数主机建站助手?
小程序网站制作需要准备什么资料,如何制作小程序?
教育培训网站制作流程,请问edu教育网站的域名怎么申请?
建站三合一如何选?哪家性价比更高?
如何在腾讯云服务器上快速搭建个人网站?
建站为何优先选择香港服务器?
如何在阿里云部署织梦网站?
油猴 教程,油猴搜脚本为什么会网页无法显示?
建站之星好吗?新手能否轻松上手建站?
详解jQuery中基本的动画方法
制作网站的过程怎么写,用凡科建站如何制作自己的网站?
零服务器AI建站解决方案:快速部署与云端平台低成本实践
正规网站制作公司有哪些,目前国内哪家网页网站制作设计公司比较专业靠谱?口碑好?
云南网站制作公司有哪些,云南最好的招聘网站是哪个?
建站与域名管理如何高效结合?
官网自助建站系统:SEO优化+多语言支持,快速搭建专业网站
网站制作与设计教程,如何制作一个企业网站,建设网站的基本步骤有哪些?
建站主机CVM配置优化、SEO策略与性能提升指南
建站之星云端配置指南:模板选择与SEO优化一键生成
成都网站制作公司哪家好,四川省职工服务网是做什么用?
公众号网站制作网页,微信公众号怎么制作?
*请认真填写需求信息,我们会在24小时内与您取得联系。