golang POST data using the Content-Type multipart/form-data

匿名 (未验证) 提交于 2019-12-03 02:44:02

问题:

I'm trying to upload images from my computer to a website using go. Usually, I use a bash script who send file a key to the serveur:

curl -F "image"=@"IMAGEFILE" -F "key"="KEY" URL 

it's work fine, but I'm trying to convert this request into my golang program.

http://matt.aimonetti.net/posts/2013/07/01/golang-multipart-file-upload-example/

I tried this link and many other. But for each code that I try, the response for the server is "no image sended". And I've no idea why. If someone know what's happend with the exemple above.

Thanks

回答1:

Here's some sample code.

In short, you'll need to use the mime/multipart package to build the form.

package sample  import (     "bytes"     "fmt"     "io"     "mime/multipart"     "net/http"     "os" )  func Upload(url, file string) (err error) {     // Prepare a form that you will submit to that URL.     var b bytes.Buffer     w := multipart.NewWriter(&b)     // Add your image file     f, err := os.Open(file)     if err != nil {         return      }     defer f.Close()     fw, err := w.CreateFormFile("image", file)     if err != nil {         return      }     if _, err = io.Copy(fw, f); err != nil {         return     }     // Add the other fields     if fw, err = w.CreateFormField("key"); err != nil {         return     }     if _, err = fw.Write([]byte("KEY")); err != nil {         return     }     // Don't forget to close the multipart writer.     // If you don't close it, your request will be missing the terminating boundary.     w.Close()      // Now that you have a form, you can submit it to your handler.     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())      // Submit the request     client := &http.Client{}     res, err := client.Do(req)     if err != nil {         return      }      // Check the response     if res.StatusCode != http.StatusOK {         err = fmt.Errorf("bad status: %s", res.Status)     }     return } 


回答2:

Regarding attila-o's post, the request header doesn't have the boundary since the Writer is closed already.

// after the close, the bounday will be nil. w.Close() ... req.Header.Set("Content-Type", w.FormDataContentType()) 

So, it should close after the set, I think.

req.Header.Set("Content-Type", w.FormDataContentType()) w.Close() 


回答3:

I have found this tutorial very helpful to clarify my confusions about file uploading in Go.

Basically you upload the file via ajax using form-data on a client and use the following small snippet of Go code on the server:

file, handler, err := r.FormFile("img") // img is the key of the form-data if err != nil {     fmt.Println(err)     return } defer file.Close()  fmt.Println("File is good") fmt.Println(handler.Filename) fmt.Println() fmt.Println(handler.Header)   f, err := os.OpenFile(handler.Filename, os.O_WRONLY|os.O_CREATE, 0666) if err != nil {     fmt.Println(err)     return } defer f.Close() io.Copy(f, file) 

Here r is *http.Request. P.S. this just stores the file in the same folder and does not perform any security checks.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!