4

Problem: .parse() method from node package 'formidable' doesn't want to execute.

Reasources: The code snippet on this site is what I was using for reference, if that helps: https://github.com/felixge/node-formidable

Description: I am trying to create a website which can upload and store a file with nodejs for the server side code. I am achieving this using httpdispatcher package for directing the user, and formidable package for processing an upload form.

I am encountering a problem where every time, my program executes as expected up until the formidable package method parse() and then stops doing anything. The browser tab sits attempting to reload, and after almost 5 minutes shows an error along the lines of 'server didn't send anything back'. I don't receive and errors from node.

Obviously, this code only sends the processed form data back to the user. I have just simplified it as far as I think is reasonable.

Code: nodejs, (server.js file):

var http = require('http');
console.log('http loaded');
var fs = require('fs');
console.log('fs loaded');
var dispatcher = require('httpdispatcher');
console.log('dispatcher loaded');

var formidable = require('formidable');
console.log('formidable loaded');
var util = require('util');
console.log('util loaded');

dispatcher.setStaticDirname('.');
dispatcher.setStatic('resources');
dispatcher.onGet('/main', function(request, response){
    response.writeHead(200, {'Content-Type': 'text/html'});
    fs.readFile('index.html', function(error, html){
        response.end(html); //Callbacked to prevent async send of file read
    })
});
dispatcher.onPost('/main', function(request, response){
    console.log('upload url accessed');
    processForm(request, response);
});

const PORT = 8000;

function processForm(request, response){
    console.log('processForm launched');
    var form = new formidable.IncomingForm();
    console.log('formidable initailised');
    form.parse(request, function(error, fields, files){
        console.log('form parsing started');
        response.writeHead(200, {'content-type': 'text/plain'});
        console.log('head written');
        response.write('data recieved:\n\n');
        response.end(util.inspect({fields: fields, files: files}));
        console.log('form passing ended');
    });
}
function saveImage(){
    console.log('saveImage called');
    fs.readFile(request.files.uploadImage.path, function(error, imageData){
        console.log('reading file');
        path = './uploadedImages';
        fs.writeFile(path, imageData, function(error){
            console.log('fs encountered an error: %s', error);
        });
    });
    console.log('saveImage ended');
}
function handleRequest(request, response){
    console.log('request handler started');
    console.log('request method: %s', request.method);
    try{
        console.log(`URL: %s was requested`, request.url);
        dispatcher.dispatch(request, response);
    }
    catch(error){
        console.log(`httpdispatcher encountered an error: %s`, error);
    }
    console.log('request handler ended');
}

var server = http.createServer(handleRequest);
server.listen(PORT, function(){
    //Callback triggered when server is successfully listening.
    console.log("Server listening on: http://localhost:%s", PORT);
});

Code: html, (index.html file):

<!DOCTYPE html>
<html>
<head></head>
<body>
    <form action="" method="post" enctype="multipart/form-data">
        <input type="file" name="uploadImage">
    </form>
    <form action="" enctype="multipart/form-data" method="post">
         <fieldset>
            <label for="imageTitle">Image title:</label>
            <input type="text" id="imageTitle" name="imageTitle" placeholder="Enter title of image" />
            <br />
            <label for="imageDesription">Image desription:</label>
            <textarea id="imageDesription" name="imageDesription" placeholder="Enter a description of the image"></textarea>
            <br />
            <input type="submit" value="Upload Image" />
         </fieldset>
      </form>
</body>
</html>

Thank you in advance.

6
  • shouldn't the action of the form be like action="/upload"?
    – Aᴍɪʀ
    Commented Nov 5, 2016 at 4:51
  • @Amir I don't know, but I doesn't that redirect to a differant page? Is that what I need to be doing? Commented Nov 5, 2016 at 4:59
  • You are handling the form data on /upload, so the forms should point to there. Or you can handle the form on /main. But that's not the problem.
    – Aᴍɪʀ
    Commented Nov 5, 2016 at 5:06
  • Why don't you use express? The problem might be with httpdispatcher.
    – Aᴍɪʀ
    Commented Nov 5, 2016 at 5:08
  • @Amir I will probably end up doing that. Thank you Commented Nov 5, 2016 at 5:11

1 Answer 1

1

Looks like httpdispatcher modifies request buffers so formidable can not extract the form values from it.

To test this, you can handle post request directly inside http module's callback, without dispatching the request:

function handleRequest(request, response){
    console.log('request handler started');
    console.log('request method: %s', request.method);

     // HERE
    if (request.method == 'POST') {
        processForm(request, response);
        return;
    }

    try{
        console.log(`URL: %s was requested`, request.url);
        dispatcher.dispatch(request, response);
    }
    catch(error){
        console.log(`httpdispatcher encountered an error: %s`, error);
    }
    console.log('request handler ended');
}

I would suggest you use express to dispatch the request based on method and route.

1
  • Thank you. I will try and get this to work. Express seems like a better option at this point anyway. Commented Nov 5, 2016 at 5:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.