I am using vaadin upload to upload files on web application with polymer. And I am using golang for back-end.
<vaadin-upload target="../upload" max-files="20" accept="application/pdf,image/*"
method="POST"> </vaadin-upload>
I checked that encoding type used in vaadin upload is multipart/form-data. My golang code is below.
func upload(w http.ResponseWriter, r *http.Request) {
fmt.Println("method:", r.Method)
if r.Method == "GET" {
crutime := time.Now().Unix()
h := md5.New()
io.WriteString(h, strconv.FormatInt(crutime, 10))
token := fmt.Sprintf("%x", h.Sum(nil))
t, _ := template.ParseFiles("upload.gtpl")
t.Execute(w, token)
} else {
r.ParseMultipartForm(32 << 20)
file, handler, err := r.FormFile("uploadFile")
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
fmt.Fprintf(w, "%v", handler.Header)
f, err := os.OpenFile("./test/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
io.Copy(f, file)
}
}
It gives error on server side http: no such file. I checked this error is returned by FormFile when the provided file field name is either not present in the request or not a file field.
How do I correct my form file name. Although everything seems fine on front-end
Did a quick test and it appears that the vaadin-upload
uses file
as the form data parameter name for the file. So in the line
file, handler, err := r.FormFile("uploadFile")
replace uploadFile
with file
and it should work.
It is documented on the vaadin homepage that
In order to support simultaneous uploads, instead of reusing the same FormData and XMLHttpRequest, we create a new one for each file. It is therefore alright for the server to only consider receiving one file per request.
However, I didn't see the parameter name (file
) documented, so to be safe you should write your code so that it wouldn't use the name, ie something like
r.ParseMultipartForm(32 << 20)
m := r.MultipartForm
for _, v := range m.File {
for _, f := range v {
file, err := f.Open()
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
// do something with the file data
...
}
}
Answering my own question for those who are facing same problem. Found out some code which can access file without knowing the key value.
func UploadHandler(res http.ResponseWriter, req *http.Request) {
var (
status int
err error
)
defer func() {
if nil != err {
http.Error(res, err.Error(), status)
}
}()
// parse request
// const _24K = (1 << 20) * 24
if err = req.ParseMultipartForm(32 << 20); nil != err {
status = http.StatusInternalServerError
return
}
fmt.Println("No memory problem")
for _, fheaders := range req.MultipartForm.File {
for _, hdr := range fheaders {
// open uploaded
var infile multipart.File
if infile, err = hdr.Open(); nil != err {
status = http.StatusInternalServerError
return
}
// open destination
var outfile *os.File
if outfile, err = os.Create("./uploaded/" + hdr.Filename); nil != err {
status = http.StatusInternalServerError
return
}
// 32K buffer copy
var written int64
if written, err = io.Copy(outfile, infile); nil != err {
status = http.StatusInternalServerError
return
}
res.Write([]byte("uploaded file:" + hdr.Filename + ";length:" + strconv.Itoa(int(written))))
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With