2

How do you parse formdata at nodejs side?

I’m doing http POST requests to a nodejs server. Here is a snippet of the Javascript(angular in it). My aim is to upload a file and add a JSON to it. So I’m uploading a picture and a json that has {account: xx , sitename:xyz, etc..}

$scope.upload[index] = $upload.upload({
                url :  'http://localhost:1215/facility',
                method: $scope.httpMethod,
                headers: {'Content-Type': 'multipart/form-data','X-Requested-With':'XMLHttpRequest'},
                data :  $scope.selectedSite,
                withCredentials:true,
                file: $scope.selectedFiles[index],
                fileFormDataName: 'myFile'
            }).then(function(response) {
                $scope.uploadResult.push(response.data);
            }, null, function(evt) {
                $scope.progress[index] = parseInt(100.0 * evt.loaded / evt.total);
            }).xhr(function(xhr){
                xhr.upload.addEventListener('abort', function(){console.log('aborted complete')}, false);
            });
}

I am using angular-upload-file that allows me to construct the formdata.It combines the selectedSite json with the file and the filename. Found it on github and it is doing the trick. [angular-file-upload][1] https://github.com/danialfarid/angular-file-upload. Fiddler confirms that.

The way that this library angular-file-upload works is that the http with XMLHTTPREQUEST will results in the body referring to the formdata which looks like this

{  
   site:xyz,
   account:xxx,
   etc
   Myfile: somefile.txt: fileContent 
}

At the server side, regardless of what I do I cannot get the value of the json key (e.g. xyz) or the content of the file. I am not yet trying to save the file or manipulate the json yet.

router.post('/', passport_utils.ensureAuthenticated,
    function(req, res)
    {
        var data ,file= {};//reconstruct site from formdata

        console.log("req.body"  + req.body);
        //jsonData = JSON.stringify(data);
        for(var field in req.body){
            console.log(field); //prints all the json elements but not the file or the filename
                if(field.match(‘site’))
                    console.log("HI    username "+ field.site) ;
                if(field.match('account'))
                    console.log("hi data " + field.name);
        res.send(200);
  }

I tried doing field[jsonkey] or field.jsonkey to get the value. The above for loop confirms that i have the keys but not the value. All those result in "undefined" for the value. The key value shows up but not the value

1
  • if(field.match(‘site’)) is not valid JavaScript. Commented May 12, 2014 at 0:04

2 Answers 2

3

It looks like you are using Express 4, if you are, you need to set the body parser in your server:

var bodyParser     = require('body-parser');
//...

var app            = express();
//...
app.use(bodyParser());  // pull information from html in POST

In earlier version of Express you only needed to add the body parser from the framework itself:

app.use(express.bodyParser());                      // pull information from html in POST

Since version 4 removed support for connect now you need to add your custom support for multipart/form data to parser multi/part POSTs, so you will have to to do something like:

var busboy = require('connect-busboy');    
app.use(busboy());
Sign up to request clarification or add additional context in comments.

3 Comments

body-parser does not parse multipart/form-data requests. You have to use another module such as connect-busboy, connect-multiparty, multer, etc.
@mscdex thanks for highlighting it, it took me a while to type the example but more to come soon
Thanks guys. now that i know those lib exist i will look into it. [stackoverflow.com/questions/20228203/…
1

I have fixed using the below idea

In server side, I have used json middle-ware of body-parser

app.use(bodyParser.json());

in Agular side, send in the headers content type of "application/json"

headers: {'Content-Type': 'application/json' }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.