Node.js - File Upload

Updated: 2018-12-09

Background

Enctype

3 ways to encode HTML forms

  • application/x-www-form-urlencoded: default, more or less the same as a query string on the end of the URL.
  • multipart/form-data: if has file uploads(<input type="file">)
  • text/plain(Do NOT use)

Packages

  • body-parser: can parse bodies but NOT multipart bodies
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));

// parse application/json
app.use(bodyParser.json());
  • multer: handle multipart/form-data
var express = require("express");
var multer = require("multer");

var app = express();
app.use(multer({ dest: "./uploads/" }));

Solution

HTML

<input id="file-upload" type="file" name="foo" />

Where id is used for jQuery selector to find this div, and “name” is used for looking for the file(there could be multiple files, identified by names).

Server

exports.uploadFile = function(req, res) {
    var html = fs.readFileSync(req.files.foo.path);
    // ...
    res.json({...});
}

req.files is a collection of files, if the filename is “foo”, then the info about this file is stored in req.files.foo, and req.files.foo.path is a local temporary path storing the uploaded file. Add the POST to app:

app.post('/uploadFile', yourModule.uploadFile);

Client(jQuery)

$("#btn-upload").click(function() {
  var data = new FormData();
  data.append("foo", $("#file-upload")[0].files[0]);

  $.ajax({
    url: "/uploadFile",
    type: "POST",
    success: function(d) {
      console.log(d);
    },
    error: function() {
      console.log("error");
    },
    data: data,
    cache: false,
    contentType: false,
    processData: false
  });
});

To get the file from the <input>, use $('#file-upload')[0].files[0]

The success callback will receive whatever the server returned.