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.
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.
Just make sure you're reading binary data, as mentioned here —
https://docs.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
.