7

I am trying to create an Azure function that handles file upload. I have tried different options (trying to read from request directly or using formidable).

For both these cases I am getting following error when the function is executed.

Exception while executing function: Functions.UploadFile. mscorlib: TypeError: req.on is not a function  
    at IncomingForm.parse (D:\home\site\wwwroot\node_modules\formidable\lib\incoming_form.js:117:6)  
    at module.exports (D:\home\site\wwwroot\UploadFile\index.js:5:10)  
    at D:\Program Files (x86)\SiteExtensions\Functions\1.0.11702\bin\azurefunctions\functions.js:106:24.  

The function code is as below

var formidable = require("formidable");  

module.exports = function (context, request) {  
    context.log('JavaScript HTTP trigger function processed a request.');      
    var form = new formidable.IncomingForm();  
    form.parse(request, function (err, fields, files) {  
        context.res = { body : "uploaded"};  
    });  
    context.done();  
};  

Any help is appreciated.

huysmania
  • 1,054
  • 5
  • 11

2 Answers2

5

I got it to work with following. Request object is neither a Stream nor an EventEmitter in Azure functions (and in AWS lambda too). It just has body and headers populated. I took help from https://www.npmjs.com/package/parse-multipart. I had to tune it for Azure functions

var multipart = require("parse-multipart");

module.exports = function (context, request) {  
    context.log('JavaScript HTTP trigger function processed a request.'); 
    // encode body to base64 string
    var bodyBuffer = Buffer.from(request.body);
    // get boundary for multipart data e.g. ------WebKitFormBoundaryDtbT5UpPj83kllfw
    var boundary = multipart.getBoundary(request.headers['content-type']);
    // parse the body
    var parts = multipart.Parse(bodyBuffer, boundary);
    context.res = { body : { name : parts[0].filename, type: parts[0].type, data: parts[0].data.length}}; 
    context.done();  
};

This seems to work better with Azure Function 2.x runtime (beta). I have updated the code. I have tested this with PDF, JPG, PNG and XLSX.

  • 2
    the above code works if there is the only file, but fails if we have other fields along with a file. – Adnan Aug 27 '20 at 15:55
0

Just make sure you're reading binary data, as mentioned here —
https://learn.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings#binding-datatype-property

For languages that are dynamically typed such as JavaScript, use the dataType property in the function.json file. For example, to read the content of an HTTP request in binary format, set dataType to binary:

{
   "type": "httpTrigger",
   "name": "req",
   "direction": "in",
   "dataType": "binary"
}

Other options for dataType are stream and string.

evilSnobu
  • 24,582
  • 8
  • 41
  • 71
  • I tried binary and stream. It did not work. From following post it seems that request is not a stream in Azure hence events are not working: https://stackoverflow.com/questions/43614581/deploying-a-node-app-on-azure-functions – Prashant Ambardekar May 28 '18 at 04:59