Golang Multipart请求上传PDF报Unexpected EOF错误,图片上传正常
问题解决思路与代码改进方案
核心问题分析
你遇到的unexpected EOF错误,大概率是ParseMultipartForm自动处理请求体时的边界解析或临时文件读写异常导致的——虽然图片上传正常,但PDF文件的二进制结构可能触发了该方法的隐性bug,尤其是重复请求时的资源残留问题。
代码改进方案:改用流式解析(MultipartReader)
放弃ParseMultipartForm,直接使用r.MultipartReader()手动流式解析请求体,这种方式更底层、更稳定,能避免自动解析带来的EOF异常:
import ( "io" "net/http" "log" // 你的其他依赖 ) func UpdateItem(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() log.Info("Request Content Length:", r.ContentLength) // 获取MultipartReader,流式解析请求 reader, err := r.MultipartReader() if err != nil { log.Error("UpdateItem: Failed to get multipart reader ", err) utils.ErrorJSON(w, err, http.StatusBadRequest) return } // 遍历所有表单部分(字段+文件) for { part, err := reader.NextPart() if err == io.EOF { break // 解析完成 } if err != nil { log.Error("UpdateItem: Failed to read multipart part ", err) utils.ErrorJSON(w, err, http.StatusBadRequest) return } // 处理普通表单字段 if part.FileName() == "" { fieldName := part.FormName() fieldValue, err := io.ReadAll(part) if err != nil { log.Error("UpdateItem: Failed to read form field ", err) utils.ErrorJSON(w, err, http.StatusBadRequest) return } // 这里添加字段处理逻辑,比如存入变量 // example: formData[fieldName] = string(fieldValue) } else { // 处理上传的PDF文件 fileName := part.FileName() fileContent, err := io.ReadAll(part) if err != nil { log.Error("UpdateItem: Failed to read uploaded file ", err) utils.ErrorJSON(w, err, http.StatusBadRequest) return } // 这里添加PDF文件处理逻辑,比如保存到磁盘/数据库 // example: os.WriteFile("./uploads/"+fileName, fileContent, 0644) } // 必须关闭part,避免资源泄漏 _ = part.Close() } // 后续业务逻辑... }
额外检查点
客户端请求格式验证:用curl重复测试上传PDF,确认客户端是否发送了完整的请求体:
curl -X POST -F "file=@your-test.pdf" http://your-api-endpoint/update-item如果curl测试无异常,说明问题可能出在原有客户端的请求实现上。
服务器临时目录权限:若坚持使用
ParseMultipartForm,需检查服务器临时文件目录(默认os.TempDir())的读写权限——该方法会将超过内存限制的文件写入临时目录,权限不足会触发写入失败,进而导致EOF错误。中间件请求体读取检查:确认是否有前置中间件提前读取了
r.Body(比如日志中间件),若r.Body的读取指针已移动,ParseMultipartForm会无法读取完整请求体,触发EOF错误。
内容的提问来源于stack exchange,提问作者Leon
相关产品推荐
相关产品推荐

