imroc / req

Simple Go HTTP client with Black Magic
https://req.cool
MIT License
4.25k stars 347 forks source link

关于multipart/form-data文件上传的支持 #299

Closed CHNfrankfang closed 10 months ago

CHNfrankfang commented 10 months ago

首先感谢作者的无私付出,此库应该是go生态下最好用的req库了 但是最近在尝试上传文件的时候发现了这样的请求无法上传成功,尝试了多种方式组合也没能成功 req方法

    var ret Ret
    path, _ := os.Getwd()
    f, err := os.Open(fmt.Sprintf("%s/case_template.xlsx", path))
    if err != nil {
        fmt.Println(err)
    }
    b, err := ioutil.ReadAll(f)
    if err != nil {
        fmt.Println(err)
    }

    req := req.C().DevMode()
    s := req.R().EnableForceMultipart().
        SetHeaders(map[string]string{
            "Apikey": token, "username": username,
        }).SetFormDataAnyType(map[string]interface{}{
        "file": string(b), "parentid": "2201132506925",
    }).SetResult(&ret)
    s.Post(fmt.Sprintf("%s?group_id=%s", Host, groupID))

}

原生库方法


import (
   "fmt"
   "bytes"
   "mime/multipart"
   "os"
   "path/filepath"
   "io"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "domain"
   method := "POST"

   payload := &bytes.Buffer{}
   writer := multipart.NewWriter(payload)
   file, errFile1 := os.Open("./case_template.xlsx")
   defer file.Close()
   part1,
         errFile1 := writer.CreateFormFile("file",filepath.Base("./case_template.xlsx"))
   _, errFile1 = io.Copy(part1, file)
   if errFile1 != nil {
      fmt.Println(errFile1)
      return
   }
   _ = writer.WriteField("parentid", "2201132506925")
   err := writer.Close()
   if err != nil {
      fmt.Println(err)
      return
   }

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Apikey", "apikey")
   req.Header.Add("username", "francofang")
   req.Header.Add("User-Agent", "Apifox/1.0.0 (https://apifox.com)")
   req.Header.Add("Accept", "*/*")
   req.Header.Add("Host", "api-kylin.intra.xiaojukeji.com")
   req.Header.Add("Connection", "keep-alive")
   req.Header.Add("Content-Type", "multipart/form-data; boundary=--------------------------930815017808735524064819")

   req.Header.Set("Content-Type", writer.FormDataContentType())
   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}

还请不吝赐教 像这种原生操作该怎么替换为req的相关api组合

imroc commented 10 months ago

最小改动:

    var ret Ret
    path, _ := os.Getwd()
    f, err := os.Open(fmt.Sprintf("%s/case_template.xlsx", path))
    if err != nil {
        fmt.Println(err)
    }
    b, err := ioutil.ReadAll(f)
    if err != nil {
        fmt.Println(err)
    }

    req := req.C().DevMode()
    s := req.R().
        SetFileBytes("file", "case_template.xlsx", b).
        SetHeaders(map[string]string{
            "Apikey": token, "username": username,
        }).
        SetFormData(map[string]string{
            "parentid": "2201132506925",
        }).
        SetResult(&ret)
    s.Post(fmt.Sprintf("%s?group_id=%s", Host, groupID))

建议用法:

    var ret Ret
    path, _ := os.Getwd()
    client := req.C().DevMode()
    s := client.R().
        SetFile("file", fmt.Sprintf("%s/case_template.xlsx", path)).
        SetFormData(map[string]string{
            "parentid": "2201132506925",
        }).
        SetHeaders(map[string]string{
            "Apikey": token, "username": username,
        }).
        SetParam("group_id", groupID).
        SetResult(&ret)
    s.Post(Host)