Search code examples
node.jsexpresspostmanmultipartform-datamulter

form-data request body is empty


I'm trying to send an image and some data from an API to another. The image is stored in memory with multer. But when I want to send it, the body is just empty. I tried the same request with postman and it worked perfectly.

postman test postman test image

server test server test image

Here is some code. I removed some of it so you can read it better

export const saveImage = async ({ image, name, folder, options }: { image: any, name?: any, folder: string, options?: any }) => {
    try {
        const fd = new FormData();
        fd.append("image", image.buffer, image.originalname);
        if(options) {
            fd.append("options[resize][height]", options?.resize?.height);
            fd.append("options[resize][width]", options?.resize?.width);
        }
        if(name) fd.append("name", name);
        fd.append("folder", folder);
        fd.append("servideId", IMAGES_ID);
        fd.append("serviceSecret", IMAGES_SECRET);

        console.log(fd)

        const formHeaders = fd.getHeaders();

        const request = await axios.post(`${IMAGES_URL}/api/images`, {
            headers: formHeaders,
            body: fd
        });

        return request.data.id;
    } catch (error) {
        const { response } = error;
        console.log(response.request.data)
        if(error?.response?.data?.error) {
            throw { statusCode: error.response.status, message: error.response.data.error }
        }
        console.error("Images API", error);
        throw new InternalError("Something gone wrong");
    }
}

When I log the FormData, I can see in _streams, the data that I'm sending, but the Images API receives an empty body. FormData screenshot

If you need more information tell me, please! Thank you


Solution

  • The axios API for the post method is: axios.post(url[, data[, config]]). The second argument must always be the data you send along.

    In your case axios thinks { headers: formHeaders, body: fd } is the body and the request ends up being application/json. To send a file with data using axios in Node.js, do the following:

    const response = await axios.post(`${IMAGES_URL}/api/images`, fd, {
      headers: {
        ...formHeaders,
        'X-Custom-Header': 'lala', // optional
      },
    });
    

    Your question inspired me to turn this answer into an article — Send a File With Axios in Node.js. It covers a few common pitfalls and you'll learn how to send files that are stored as a Buffer or coming from a Stream.