Search code examples
node.jsreactjsexpresssuperagent

Superagent .attach() file or buffer data is empty


I ran into this issue where superagent does not properly attach a file or a buffer into the request and the reason I mentioned empty is due to the form data looking like :

------WebKitFormBoundaryy6T3XReWRFT1KfFm
Content-Disposition: form-data; name="media"


------WebKitFormBoundaryy6T3XReWRFT1KfFm--

there isnt any information on the file and it comes up as empty media:

The code I'm using is simple:

.post(`${API_ROOT}${url}`)
        .withCredentials()
        .attach('media', body.media, 'filename.jpg')

Where body.media is:

asBuffer(file, callback) {
    const reader = new FileReader();
    reader.addEventListener('load', () => callback(reader.result));
    reader.readAsDataURL(file);
}
asBuffer(file, ((b) => {
    body.media = b;
}));

or

body.media = new FormData();
body.media.append('file', inputFile, inputFileName);

or along with after asBuffer

Buffer.from(body.media, 'base64');

where inputFile is of type File. I have also played around with attach and omitted the filename when the body.media was not of type Buffer.

I don't believe there is a problem on my end as using .send(body.media) actually attaches the file to the request formdata and I can see it in the back-end server. Only the .attach() function does not work properly and I need it to as I also need to send fields.

The only workaround I found at this moment was this:

const mediaFile = body.media;
delete body.media;
.post(...)
    .withCredentials()
    .query(body)
    .send(mediaFile)

and I dont actually feel comfortable getting a huge url just to be able to send a file along with my fields. I've seen some issues like this posted already, but none had seem to have an answer.


Solution

  • After inspecting

    https://github.com/visionmedia/superagent/blob/master/lib/client.js#L571

    shows that superagent has its own FormData variable to which it appends attached files to - meaning the use of FormData of my own is redundant and therefore causes nesting which results in an empty payload.

    So just passing an inputFile of type File to .attach() solves the problem.

    Furthermore for the fields I had a dozen of them to which solution was:

    .field('fieldName', JSON.stringify(body))

    And in the back-end server simply: JSON.parse(req.body.fieldName) to get the request payload in JSON format.