Golang FormFile报http: no such file Vue+Axios文件上传问题排查
问题根因
问题核心是前端未正确序列化文件对象,直接将JS原生File类型变量转为默认字符串[object File]传输,没有按文件上传规范封装为multipart/form-data格式,导致后端无法识别为文件字段。
前端修复方案(Vue + Axios)
- 必须使用
FormData对象封装所有请求参数,禁止直接传递普通JSON对象提交文件 - 通过
append方法将文件对象加入FormData,字段名使用约定的Model,第二个参数直接传File对象,不要做任何字符串转换 - 不要手动设置
Content-Type请求头,Axios会自动识别FormData对象并生成带boundary参数的正确请求头,手动设置会丢失boundary导致后端解析失败 - 若配置了Axios全局请求拦截器统一做
JSON.stringify序列化,需要添加判断逻辑,遇到FormData类型的请求体跳过序列化步骤
前端示例代码:
// 假设从<input type="file">的change事件中获取到的文件对象为 uploadFile const formData = new FormData() formData.append('Model', uploadFile) // 发起PUT请求 axios.put('/你的上传接口路径', formData) .then(res => { // 处理成功逻辑 }) .catch(err => { // 处理错误逻辑 })
后端修复方案(Golang + Chi)
- 调用
r.FormFile之前必须先执行r.ParseMultipartForm(最大内存)解析multipart表单,参数为最大占用内存大小,超出部分会自动写入临时磁盘文件 - Chi框架原生支持PUT请求的表单解析,无需额外适配,只要路由注册时指定方法为
MethodPut即可
后端示例代码:
func uploadHandle(w http.ResponseWriter, r *http.Request) { // 解析表单,最大占用内存10MB,可根据业务调整 err := r.ParseMultipartForm(10 << 20) if err != nil { http.Error(w, "表单解析失败", http.StatusBadRequest) return } // 读取Model字段的上传文件 file, fileHeader, err := r.FormFile("Model") if err != nil { http.Error(w, "获取文件失败:"+err.Error(), http.StatusBadRequest) return } defer file.Close() // 后续处理文件逻辑:保存到本地/云存储、校验文件格式大小等 // log.Println("收到上传文件:", fileHeader.Filename, fileHeader.Size) }
验证标准
修改完成后抓包验证请求符合以下两点即可:
- 请求头
Content-Type值为multipart/form-data; boundary=xxxxxx格式 - 请求体中
Model字段对应值为文件二进制内容,包含文件名等元信息,不是[object File]字符串
内容的提问来源于stack exchange,提问作者Dmitry
相关产品推荐
相关产品推荐

