How to Process Multipart Form Data with a Netlify Function

Hey I’m trying to upload a file using the lambda function but I’m not able to return the actual file can you help me with that.

I’m getting this result,

{
  filename: 'audiojoinerkit (5).mp3',
  type: 'audio/mpeg',
  content: <Buffer 49 44 33 04 00 00 00 00 00 23 54 53 53 45 00 00 00 0f 00 00 03 4c 61 76 66 35 38 2e 34 35 2e 31 30 30 00 00 00
00 00 00 00 00 00 00 00 ef bf bd ef bf ... 221928 more bytes>
}

and according to this netlify post - Link I can perform any operation on this but I don’t know how to convert this data into the actual file.

If I try to decode it, I’m getting something like this R���

I’m uploading a image file here.

My code

const fs = require("fs");

const Busboy = require("busboy");

exports.handler = async function (event, context) {

  const fields = await parseMultipartForm(event);

  let file = fields.file;

  console.log(fields);

  console.log(file);

  let data = Buffer.from(file.content).toString();

  console.log(data);

  fs.writeFile(`${file.filename}`, file.content.toString("utf-8"), function (err) {

      if (err) return console.log(err);

      console.log("Hello World > helloworld.txt");

    }

  );

  return {

    statusCode: 200,

    headers: {

      "Access-Control-Allow-Origin": "*",

      "Access-Control-Allow-Credentials": true,

    },

    body: data,

  };

};

function parseMultipartForm(event) {

  return new Promise((resolve) => {

    // we'll store all form fields inside of this

    const fields = {};

    // let's instantiate our busboy instance!

    const busboy = new Busboy({

      // it uses request headers

      // to extract the form boundary value (the ----WebKitFormBoundary thing)

      headers: event.headers,

    });

    // before parsing anything, we need to set up some handlers.

    // whenever busboy comes across a file ...

    busboy.on(

      "file",

      (fieldname, filestream, filename, transferEncoding, mimeType) => {

        // ... we take a look at the file's data ...

        filestream.on("data", (data) => {

          // ... and write the file's name, type and content into `fields`.

          fields[fieldname] = {

            filename,

            type: mimeType,

            content: data,

          };

        });

      }

    );

    // whenever busboy comes across a normal field ...

    busboy.on("field", (fieldName, value) => {

      // ... we write its value into `fields`.

      fields[fieldName] = value;

    });

    // once busboy is finished, we resolve the promise with the resulted fields.

    busboy.on("finish", () => {

      resolve(fields);

    });

    // now that all handlers are set up, we can finally start processing our request!

    busboy.write(event.body);

  });

}

and I’m sending request from postman.

Hi @Naveen1401

Welcome to the forums.

I can get neither the function you have posted, nor that in the linked blog working.

Using your function I get a Busboy is not a constructor error, no data ever returned and nothing logged to console.

What version of busboy are you using?

What are you trying to do with this function? Are you simply wishing to return the file content or post it elsewhere?

Hi, @coelmay I’m using the current version of busboy,

I’m attaching the blog Link again if it still doesn’t work then please search it as ( How to Process Multipart Form Data with a Netlify Function ) in Netlify blogs,

And my main aim is to run ffmeg js library (on serverless lambda function) for which I’m trying to return the actual file here.

I read the blog. And I tried the code as presented. It didn’t work either as it appears (based on the busboy README using an import isn’t supported.

Using busboy@0.3.1 the import seems to work when

import * as Busboy from 'busboy'

is changed to

import Busboy from 'busboy'

however the function times out (take more than 10 seconds) even with a 10kb image.

If you are planning to run ffmeg to transform images, keep in mind the execution time limit (which can get raised to 26 seconds on request.) Also worth reading are

You might find this answer helpful @Naveen1401 as it contains a workable function (need to change const busboy = new Busboy({headers: event.headers) to const busboy = Busboy({headers: event.headers}) if using busboy@1.3.0 I found)