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

转发客户端Multipart文件至外部API时MIME类型异常问题

解决Multipart转发文件时MIME类型无效的问题

问题核心在于multipart.Writer.CreateFormFile方法会默认将文件的Content-Type设为application/octet-stream,但目标API要求使用文件实际对应的MIME类型(如图片类的image/jpeg、image/png等)。

修复方案

  1. 优先从原请求的文件头中获取真实MIME类型;若原请求未提供,则根据文件名扩展名手动推断。
  2. 放弃使用CreateFormFile,改为手动创建multipart表单部分,明确指定正确的Content-Type。

修改后的代码

func forwardFile(r *http.Request) (string, error) {
    file, fileHandler, err := r.FormFile("image")
    if err != nil {
        return "", err
    }
    defer file.Close()

    body := &bytes.Buffer{}
    writer := multipart.NewWriter(body)

    // 获取原文件的MIME类型,为空则根据扩展名推断
    contentType := fileHandler.Header.Get("Content-Type")
    if contentType == "" {
        ext := strings.ToLower(filepath.Ext(fileHandler.Filename))
        switch ext {
        case ".jpg", ".jpeg":
            contentType = "image/jpeg"
        case ".png":
            contentType = "image/png"
        case ".pdf":
            contentType = "application/pdf"
        // 按需补充其他文件类型的MIME映射
        default:
            contentType = "application/octet-stream"
        }
    }

    // 手动创建表单部分,指定完整的请求头
    part, err := writer.CreatePart(map[string][]string{
        "Content-Disposition": {fmt.Sprintf(`form-data; name="files"; filename="%s"`, fileHandler.Filename)},
        "Content-Type":        {contentType},
    })
    if err != nil {
        return "", err
    }

    if _, err := io.Copy(part, file); err != nil {
        return "", err
    }

    writer.Close()

    req, err := http.NewRequest("POST", newUploadUrl, body)
    if err != nil {
        return "", err
    }
    req.Header.Set("Content-Type", writer.FormDataContentType())
    
    client := &http.Client{}
    response, err := client.Do(req)
    if err != nil {
        return "", err
    }
    defer response.Body.Close()

    // 读取并返回响应内容(按需调整)
    respBody, err := io.ReadAll(response.Body)
    if err != nil {
        return "", err
    }
    return string(respBody), nil
}

关键说明

  • 原请求的fileHandler.Header.Get("Content-Type")是最准确的MIME类型来源,优先使用。
  • 针对原请求未传递MIME类型的场景,通过扩展名映射可以覆盖绝大多数常见文件类型的需求。
  • 使用CreatePart替代CreateFormFile,能完全控制表单部分的HTTP头,确保目标API收到符合要求的MIME类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 19:10:51