在 golang 中包含二进制数据的 HTTP Post

我希望我能解释清楚这一点。我正在尝试发出包含二进制数据(文件)的 HTTP 发布请求。这用于 DeepStack 图像处理。在 Python 中,我有以下工作:


image_data = open(file,"rb").read()

        try:

            response = requests.post("http://deepstack.local:82/v1/vision/detection",files={"image":image_data},timeout=15).json()

在 Go 中,我从这里的基本示例开始:https ://golangtutorial.dev/tips/http-post-json-go/


为我的使用稍微修改一下,相关行是:


    data, err :=  ioutil.ReadFile(tempPath + file.Name())

    if err != nil {

        log.Print(err)

    }


    httpposturl := "http://deepstack.local:82/v1/vision/custom/combined"

    fmt.Println("HTTP JSON POST URL:", httpposturl)


    var jsonData = []byte(`{"image": ` + data + `}`)


    request, error := http.NewRequest("POST", httpposturl, bytes.NewBuffer(jsonData))

    request.Header.Set("Content-Type", "application/json; charset=UTF-8")

这会导致错误:


无效操作:`{"image": `+ 数据(类型不匹配的无类型字符串和 []byte)`


此时的“data”变量是[]uint8 ([]byte)。我从高层次上意识到出了什么问题。我正在尝试连接两种不同的数据类型。仅此而已。我已经尝试了很多东西,我敢肯定任何熟悉 Go 的人都会立即意识到这些东西是错误的(将 jsonData 声明为字节,将数据转换为字符串,使用 os.Open 而不是 ioutil.ReadFile 等)。不过,我只是有点盲目地跌跌撞撞。我找不到不使用纯字符串作为 JSON 数据的示例。


我将不胜感激任何想法。


牧羊人nacy
浏览 210回答 2
2回答

蓝山帝景

我将 Dietrich Epp 的回答标记为已接受,因为他给了我我所要求的。但是,评论中的 RedBlue 给了我真正需要的东西。谢谢你俩。下面的代码只是从这个答案中修改了一点:https ://stackoverflow.com/a/56696333/2707357将 url 变量更改为您的 DeepStack 服务器,并将文件名更改为实际存在的文件名,响应主体应返回必要的信息。package mainimport (    "bytes"    "fmt"    "io"    "io/ioutil"    "mime/multipart"    "net/http"    "os")func createMultipartFormData(fieldName, fileName string) (bytes.Buffer, *multipart.Writer) {    var b bytes.Buffer    var err error    w := multipart.NewWriter(&b)    var fw io.Writer    file := mustOpen(fileName)    if fw, err = w.CreateFormFile(fieldName, file.Name()); err != nil {        fmt.Println("Error: ", err)    }    if _, err = io.Copy(fw, file); err != nil {        fmt.Println("Error: ", err)    }    w.Close()    return b, w}func mustOpen(f string) *os.File {    r, err := os.Open(f)    if err != nil {        pwd, _ := os.Getwd()        fmt.Println("PWD: ", pwd)        panic(err)    }    return r}func main() {    url := "http://deepstack.local:82/v1/vision/custom/combined"    b, w := createMultipartFormData("image", "C:\\go_sort\\temp\\person.jpg")    req, err := http.NewRequest("POST", url, &b)    if err != nil {        return    }    // Don't forget to set the content type, this will contain the boundary.    req.Header.Set("Content-Type", w.FormDataContentType())    client := &http.Client{}    response, error := client.Do(req)    if err != nil {        panic(error)    }    defer response.Body.Close()    fmt.Println("response Status:", response.Status)    fmt.Println("response Headers:", response.Header)    body, _ := ioutil.ReadAll(response.Body)    fmt.Println("response Body:", string(body))}

扬帆大鱼

真的是这么小的错误。据我所知,这就是你所有的问题:    var data []byte // with some value    jsonData := []byte(`{"image": ` + data + `}`)    您所要做的就是将其更改为使用append()或类似的东西:    jsonData := append(        append([]byte(`{"image": `), data...),        '}')    原因是你不能在 Go 中使用+连接。[]byte不过,您可以使用append()。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go