Search code examples
node.jsdrag-and-dropmultipartform-datadropzone.js

multipart File uploads using NodeJS


I am having troubles getting file uploads to work with NodeJS. I am using Dropzone.JS to create a form that sends a POST request to /file-upload here:

<form action="/file-upload" class="dropzone dragndrop" id="my-awesome-dropzone"></form> 

Then I have a route in app.js:

app.post('/file-upload', routes.upload);

Then my handler:

exports.upload = function(req, res){
     console.log(req.files);
     res.send("OK");
}

However, the upload function here is never called. The server crashes with this error first:

events.js:69
        throw arguments[1]; // Unhandled 'error' event
                       ^
Error: Invalid data
    at WriteStream._write (fs.js:1616:31)
    at onwrite (_stream_writable.js:265:14)
    at WritableState.onwrite (_stream_writable.js:94:5)
    at fs.js:1628:5
    at Object.wrapper [as oncomplete] (fs.js:475:5)
    at process._makeCallback (node.js:321:24)

So I am not sure what I should do because it appears that this is not my fault. I followed other tutorials and saw nothing wrong. Also, when I inspect my Network under chrome dev tools, it shows:

Request URL:http://localhost:3000/file-upload
**Request Headers**
Accept:application/json
Cache-Control:no-cache
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryMmLSkbfQskfIcjfE
Origin:http://localhost:3000
Pragma:no-cache
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17
X-File-Name:Screenshot from 2013-03-20 12:23:42.png
X-Requested-With:XMLHttpRequest
**Request Payload**
------WebKitFormBoundaryMmLSkbfQskfIcjfE
Content-Disposition: form-data; name="file"; filename="Screenshot from 2013-03-20 12:23:42.png"
Content-Type: image/png


------WebKitFormBoundaryMmLSkbfQskfIcjfE--

Solution

  • @user568109 and @nick-fishman are correct; you should use the bodyParser middleware for this.

    Please see the sample code for a basic file upload form below. (Note: you will need to create an "uploads" directory to store the files.)

    file-upload.js:

    var express = require("express"),                                                                
        app = express();                                                                             
    
    // tell express to use the bodyParser middleware                                                 
    // and set upload directory                                                                      
    app.use(express.bodyParser({ keepExtensions: true, uploadDir: "uploads" }));                     
    app.engine('jade', require('jade').__express);                                                   
    
    app.post("/upload", function (request, response) {                                               
        // request.files will contain the uploaded file(s),                                          
        // keyed by the input name (in this case, "file")                                            
    
        // show the uploaded file name                                                               
        console.log("file name", request.files.file.name);                                           
        console.log("file path", request.files.file.path);                                           
    
        response.end("upload complete");                                                             
    });                                                                                              
    
    // render file upload form                                                                       
    app.get("/", function (request, response) {                                                      
        response.render("upload_form.jade");                                                         
    });                                                                                              
    
    app.listen(3000);
    

    views/upload_form.jade:

    doctype 5
    html
        head
            title Upload Form
        body
            h1 Upload File
            form(method="POST", action="/upload", enctype="multipart/form-data")
                input(type="file", name="file")
                input(type="submit")