I'm building a simple file uploader, basically for learning/testing purposes, using Vue for the front-end and Go for the back-end. Here's the code
<template>
<div class="adddocument-container">
<h1>Trascina il documento da aggiungere qui</h1>
<form action="http://localhost:55678/postdocument" method="post" enctype="multipart/form-data" style="display: flex;flex-direction: column;gap: 20px;">
<input class="fileinput" name="file[]" ref="file" type="file" multiple @input="collectDocument">
<div>
<p v-for="i in it"> {{ i.name }}</p>
</div>
<button type="submit">Upload</button>
</form>
</div>
</template>
<script>
export default {
data () {
return {
it : []
}
},
methods : {
collectDocument() {
this.it = this.$refs.file.files
}
}
}
</script>
And golang http handler function here:
package handlers
import (
"io"
"os"
"mlpbackend/dbmanager"
"net/http"
)
func PostDocument (db *dbmanager.DBClient) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(0)
for k := range r.MultipartForm.File {
file,fileheader,err := r.FormFile(k)
if err != nil {
panic(err)
}
defer file.Close()
localFileName := "./documents/" + fileheader.Filename
out, err := os.Create(localFileName)
if err != nil {
panic(err)
}
defer out.Close()
_, err = io.Copy(out,file)
if err != nil {
panic(err)
}
}
}
}
It seems I can't receive/parse more than one file in the back-end, and I can't understand why or where I am wrong.
Basically, the go handler should write all the files received in the documents
folder, but it only writes (correctly) the last one selected in the front-end.
Also, I checked the POST request sent from the front-end and it seems it correctly sends all the files (I'm basing this assumption on the request size), but I don't understand where I am wrong in the back-end at this point.
Thank you very much for any help!
The documentation for Request.FormFile says:
FormFile returns the first file for the provided form key.
The application must use the Request's MultipartForm directly to access all files for the key.
for k, fileheaders := range r.MultipartForm.File {
for _, fileheader := range fileheaders {
file, err := fileheader.Open()
if err != nil {
panic(err)
}
defer file.Close()
...
The application can access all files for the key file[]
as follows. There's no need to loop over keys as in the question.
fileheaders := r.MultipartForm.File["file[]"]
for _, fileheader := range fileheaders {
file, err := fileheader.Open()
if err != nil {
panic(err)
}
defer file.Close()
...