使用curl usign GoLang发送多部分请求

使用curl usign GoLang发送多部分请求,curl,go,multipartform-data,Curl,Go,Multipartform Data,我想把下面的代码转换成golang curl -X POST 'https://api.documo.com/v1/fax/send' \ -H 'Authorization: Basic YOUR_API_KEY' \ -H 'content-type: multipart/form-data' \ -F 'recipientFax=12345678900' \ -F 'coverPage=false' \ -F 'recipientName=John' \ -F

我想把下面的代码转换成golang

curl -X POST
  'https://api.documo.com/v1/fax/send' \
  -H 'Authorization: Basic YOUR_API_KEY' \
  -H 'content-type: multipart/form-data' \
  -F 'recipientFax=12345678900' \
  -F 'coverPage=false' \
  -F 'recipientName=John' \
  -F 'subject=test' \
  -F 'notes=test' \
  -F '=@/home/user/Documents/Sample.pdf'
请帮忙

下面是我尝试过的代码

func SendFaxDocumo(files []*multipart.FileHeader, params map[string]string) {

    request, err := SendMultipartRequest("https://api.documo.com/v1/fax/send", params, files)
    if err != nil {
        fmt.Println(err.Error())

    }
    client := &http.Client{}
    resp, err := client.Do(request)
    if err != nil {
        fmt.Println(err.Error())
    } else {
        body := &bytes.Buffer{}
        _, err := body.ReadFrom(resp.Body)
        if err != nil {
            fmt.Println(err.Error())
        }
        resp.Body.Close()
        fmt.Println(resp.StatusCode)
        fmt.Println(resp.Header)
        fmt.Println(body)
    }
}

func SendMultipartRequest(uri string, params map[string]string, files []*multipart.FileHeader) (*http.Request, error) {

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

    for i, _ := range files {
        // string_index := strconv.Itoa(i)
        file, err := files[i].Open()
        defer file.Close()
        if err != nil {
            fmt.Println(err)
        }

        doc , err := ioutil.ReadAll(file)
        if err != nil {
            fmt.Println(err,980)
        }

        part, err := writer.CreateFormFile("file",files[i].Filename)

        if err != nil {
            fmt.Println(err)
        }

        part.Write([]byte(string(doc)))
        if _, err = io.Copy(part, file); err != nil {
            fmt.Println(err)
        }

        if err != nil {
            fmt.Println(err)
        }
    }

    for key, val := range params {
        _ = writer.WriteField(key, val)
    }

    err := writer.Close()
    if err != nil {
        return nil, err
    }

    req, err := http.NewRequest("POST", uri, body)
    req.Header.Set("Content-Type", writer.FormDataContentType())
    req.Header.Set("Authorization", "Basic my_key")

    return req, err
}
我得到的错误如下: {“错误”:{“名称”:“错误”,“消息”:“不允许文件扩展名。允许的格式:tiff、gif、png、jpeg、pdf、doc、xls、ppt、pcl、eps、ps、txt、rtf、xml、fxc、docx、pptx、xlsx”}


这是从请求的url得到的响应,即使我正在通过pdf尝试它。

我只是花了很长时间研究同一个问题。在使用
httputil.DumpRequest
查看我实际传递给Documo的数据之后,我看到文件字段的内容类型头被设置为
content-type:application/octet-stream
。这是由您正在使用的
CreateFormFile
方法设置的。有关源代码,请参阅

octet-stream
子类型用作二进制文件或需要在应用程序中打开的文件的默认类型。看,或者

据我所知,问题在于,Documo希望我们明确地告诉他们我们发送给他们的是什么类型的文件,以便他们知道如何处理渲染。所以在我的例子中,
octet-stream
没有告诉他们任何事情。将文件内容类型切换到
application/pdf
就成功了

解决方案 我没有调用
writer.CreateFormField
,而是从
CreateFormFile
的源代码中复制了三行代码,并将
内容类型
硬编码到
application/pdf
的标题,而不是
application/octet stream
(注意:我的服务现在只处理PDF,所以如果您的文件类型不同,您可能需要调整此设置)

代码:


func SendMultipartRequest(uri字符串,参数映射[string]字符串,文件[]*multipart.FileHeader)(*http.Request,错误){
正文:=&bytes.Buffer{}
writer:=多部分NewWriter(正文)
对于i,z:=范围文件{
文件,错误:=文件[i]。打开()
延迟文件。关闭()
如果错误!=零{
fmt.Println(错误)
}
//////////////////////////////////////////////////////
//将CreateFormFile替换为以下内容:
h:=make(textproto.MIMEHeader)//导入“net/textproto”
h、 Set(“内容处置”,fmt.Sprintf(`formdata;name=“file”;filename=“%s”`,files[i].filename)
h、 Set(“Content Type”,“application/pdf”)//这是设置文档类型的地方
fileWriter,错误:=form.CreatePart(h)
///////////////////////////////////////////////////////
如果错误!=零{
fmt.Println(错误)
}
如果3;,err=io.Copy(fileWriter,file);err!=nil{
fmt.Println(错误)
}
如果错误!=零{
fmt.Println(错误)
}
}
对于键,val:=范围参数{
_=writer.WriteField(键,val)
}
错误:=writer.Close()
如果错误!=零{
返回零,错误
}
req,err:=http.NewRequest(“POST”,uri,body)
req.Header.Set(“内容类型”,writer.FormDataContentType())
请求标题集(“授权”、“基本我的密钥”)
返回请求,错误
}
这不是最性感的解决方案,但我现在终于能够通过Documo发送完整的文档了


希望这能有所帮助。

您似乎没有尝试过任何东西。请显示您尝试过的内容和不起作用的内容。请包括一个。@Marc我已添加了您的请求,请检查而不是您如何发送请求。我们更感兴趣的是您如何在
SendMultipartRequest
中创建请求。可能存在重复的