You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang转发multipart/form-data时出现multipart: NextPart: EOF错误如何解决

错误原因

该错误由两个核心问题共同导致:

  1. Go的http.Request.Body是仅可消费一次的IO流,你先调用了c.MultipartForm(),gin底层已经读取并消费了整个请求体来解析表单数据,后续再调用ioutil.ReadAll(c.Request.Body)只能读取到空内容,空的payload传递到目标服务后,multipart解析器读取不到有效的表单分隔符和字段内容,直接返回EOF错误。
  2. 即使你能拿到完整的原始请求体,构造新请求时没有携带原请求的Content-Type头,multipart请求的Content-Type中包含了必填的分隔边界信息boundary=xxx,目标服务缺少该信息也无法正常解析表单内容。
解决方案

按以下步骤修改即可修复问题:

  • 调整请求体读取顺序,读取完成后重置请求体,保证后续方法可以正常读取:
import (
  "bytes"
  "io"
  // 其余依赖
)

// 先读取原始请求体
body, err := ioutil.ReadAll(c.Request.Body)
if err != nil {
  // 补充错误处理逻辑
}
// 重置请求体,供后续c.MultipartForm()调用读取
c.Request.Body = io.NopCloser(bytes.NewBuffer(body))

// 再执行原有逻辑
c.MultipartForm()
postForm := c.Request.PostForm
queryParams := c.Request.URL.Query()
route := c.Request.URL.Path

serviceCode, destUrl, _ := getCityCode(queryParams, route, body, postForm)
  • 构造新请求时携带正确的Content-Type头,直接复用原请求的头信息即可:
// 直接用原始body构造请求,不需要转成string再用strings.NewReader
req, err := http.NewRequest(method, destUrl, bytes.NewBuffer(body))
if err != nil {
  // 补充错误处理逻辑
}
// 复制原请求的Content-Type,保留multipart的边界信息
req.Header.Set("Content-Type", c.Request.Header.Get("Content-Type"))

// 后续执行请求发送逻辑
  • (可选优化)如果需要兼容service_code、serviceCode、code三种参数命名,不需要重复读取请求体,可分别在查询参数、postForm、JSON body中遍历匹配三个名称的键,取第一个存在的值即可。
  • 如果你的场景包含文件上传,不能直接复用原始body,需要手动重构multipart表单,遍历原表单的字段和文件,逐个写入新请求的multipart writer中。

内容的提问来源于stack exchange,提问作者Archit Verma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 05:36:07