Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ajax Upload File to GoLang Server with Content Type Multipart

I'm trying to upload an audio file to a Golang server using a multipart form. However, Go returns the error:

multipart: NextPart: bufio: buffer full

I believe this indicates there is something not in the multipart format with my Javascript request. This is my Javascript:

function UploadFile(file) {
    var xhr = new XMLHttpRequest();


    if (file.type == "audio/mpeg" && file.size <= $id("MAX_FILE_SIZE").value) {
        // start upload
        var boundary = '---------------------------' + Math.floor(Math.random()*32768) + Math.floor(Math.random()*32768) + Math.floor(Math.random()*32768);

        xhr.open("POST", $id("upload").action, true);
        xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
        xhr.setRequestHeader("X_FILENAME", file.name);
        xhr.send(file);
    }
}

And this is my Golang server handler:

func FileHandler(w http.ResponseWriter, r *http.Request) {
    var (
        status int
        err    error
    )
    defer func() {
        if nil != err {
            http.Error(w, err.Error(), status)
        }
    }()
    // parse request with maximum memory of _24Kilobits
    const _24K = (1 << 20) * 24
    if err = r.ParseMultipartForm(_24K); nil != err {
        fmt.Println(err)
        status = http.StatusInternalServerError
        return
    }
    for _, fheaders := range r.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
            }
        w.Write([]byte("uploaded file:" + hdr.Filename + ";length:" + strconv.Itoa(int(written))))
        }
    }
}

If anyone has any ideas why I'm getting this error, I'd greatly appreciate it.

like image 405
Rjdlee Avatar asked Aug 25 '14 20:08

Rjdlee


People also ask

How do I upload my multipart data?

Follow this rules when creating a multipart form: Specify enctype="multipart/form-data" attribute on a form tag. Add a name attribute to a single input type="file" tag. DO NOT add a name attribute to any other input, select or textarea tags.

Can we upload file using AJAX?

File upload is not possible through AJAX. You can upload file, without refreshing page by using IFrame .


1 Answers

After a long, arduous battle with the Ajax request, I got it to send the right information. Here's the code I used:

var xhr = new XMLHttpRequest(),
    boundary=Math.random().toString().substr(2);

var formdata = new FormData();
formdata.append("file", file);

xhr.open("POST", $id("upload").action, true);
//xhr.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary);
xhr.send(formdata);

Note the header is no longer in use and I found you can attach data to formdata much easier than any other method such as this: How to send multipart/form-data form content by ajax (no jquery)?

like image 87
Rjdlee Avatar answered Sep 19 '22 13:09

Rjdlee