cs04iz1 cs04iz1 - 1 month ago 9
Ajax Question

jquery AJAX post formdata to node, results in empty req.body

I am trying to post data to my node server.
The data are gathered in the following HTML

<label for="files" class="col-md-4 control-label">Files</label>
<div class="col-md-7">
<input type="file" id="files" name="files[]" multiple="multiple">
</div>
<label for="name" class="col-md-4 control-label">Name</label>
<div class="col-md-7">
<input id="name" name="name" class="form-control" type="text">
</div>
<label for="url" class="col-md-4 control-label">Landing Page</label>
<div class="col-md-7">
<input id="url" name="name" class="form-control" type="text">
</div>
<button type="button" id="add_files" class="btn btn-primary" style="background-color:#27AE60;">Add Files</button>


the click event is caught by jquery, and issues the ajax post

$('#add_files').on('click', function () {
var files = $("#files")[0].files;
var name = $("#name").val();
var url = $("#url").val();
var formData = new FormData();
formData.append("name", name);
formData.append("url", url);
$.each($('#files')[0].files, function (i, file) {
formData.append('file-' + i, file);
});
$.ajax({
url: '/newData',
type: 'POST',
data: formData, // The form with the file inputs.
processData: false, // Using FormData, no need to process data.
contentType: false
}).done(function () {
console.log("Success: Files sent!");
}).fail(function () {
console.log("An error occurred, the files couldn't be sent!");
});
});


Then the post is caught by my node server but the req.boy is empty

app.post('/newData',function(req,res){
console.log("req body ",req.body)
console.log("req body ",req.body.data)
})


resulting the following:

req body {}
req body undefined


any ideas what went wrong?

My implementation is based on the following:
https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects
How can I upload files asynchronously?

Answer

As robertklep mentioned, the problem was that the body-parser can not parse multipart data. So a different parsed should be used. I used busboy-connect doing the following:

        var fstream;
        var result = [];
        var number_of_files = 1;
        req.pipe(req.busboy);
        req.busboy.on('field', function(fieldname, val) {
            field_obj = {}
            field_obj[fieldname] = val;
            result.push(field_obj);
            console.log(field_obj)
        });
        req.busboy.on('file', function(fieldname, file, filename) {
            console.log("Uploading: " + filename);
            //Path where image will be uploaded
            if (result.length > 0) {
                var file_type = filename.substr(filename.length - 4);
                filename = result[0].name + '_' + number_of_files + file_type;
                number_of_files++;
            }
            fstream = fs.createWriteStream(__dirname + "/" + filename);
            file.pipe(fstream);
            fstream.on('close', function() {
                console.log("Upload Finished of " + filename);
                result.push(filename);
            });
        });

Another parser could be used as well.