Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Uploading files using NodeJS and Express 4
<html>
<body>
<form action="/upload" enctype="multipart/form-data" method="post">
<input type="text" name="title">
<input type="file" name="file">
<input type="submit" value="Upload">
</form>
</body>
</html>
/*
* NodeJS code.
*/
// Required modules.
var express = require('express'),
http = require('http'),
formidable = require('formidable'),
fs = require('fs'),
path = require('path');
var app = express();
// All your express server code goes here.
// ...
// Upload route.
app.post('/upload', function(req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
// `file` is the name of the <input> field of type `file`
var old_path = files.file.path,
file_size = files.file.size,
file_ext = files.file.name.split('.').pop(),
index = old_path.lastIndexOf('/') + 1,
file_name = old_path.substr(index),
new_path = path.join(process.env.PWD, '/uploads/', file_name + '.' + file_ext);
fs.readFile(old_path, function(err, data) {
fs.writeFile(new_path, data, function(err) {
fs.unlink(old_path, function(err) {
if (err) {
res.status(500);
res.json({'success': false});
} else {
res.status(200);
res.json({'success': true});
}
});
});
});
});
});
@cannap
Copy link

cannap commented Oct 16, 2016

Hi i know this is a bit older but now its much simpler 💃

const formidable = require('formidable')
const path = require('path')
const uploadDir = path.join(__dirname, '/..', '/..', '/..', '/uploads/') //i made this  before the function because i use it multiple times for deleting later

function uploadMedia (req, res, next) { // This is just for my Controller same as app.post(url, function(req,res,next) {....
  var form = new formidable.IncomingForm()
  form.multiples = true
  form.keepExtensions = true
  form.uploadDir = uploadDir
  form.parse(req, (err, fields, files) => {
    if (err) return res.status(500).json({ error: err })
    res.status(200).json({ uploaded: true })
  })
  form.on('fileBegin', function (name, file) {
    const [fileName, fileExt] = file.name.split('.')
    file.path = path.join(uploadDir, `${fileName}_${new Date().getTime()}.${fileExt}`)
  })
}

@emerson-pereira
Copy link

emerson-pereira commented Mar 10, 2017

Awesome. Really helped me. Thanks

@jmepg
Copy link

jmepg commented Jul 31, 2017

This was so helpful! Thank you!

@PrinceSP
Copy link

PrinceSP commented Sep 13, 2017

it doesn't work....after i click the upload button, it's direct me to another blank page....can you help me with the problem????
i'm beginner with NodeJS......

@ssubnani
Copy link

ssubnani commented Sep 19, 2017

Where I will get the filepath on the node server ??

@kumarsubedi93
Copy link

kumarsubedi93 commented Nov 10, 2017

DD

@GaneshSaiKumar
Copy link

GaneshSaiKumar commented Dec 2, 2017

this is too lengthy can u please shorten the code

@sujith1919
Copy link

sujith1919 commented Feb 1, 2018

i have followed the method but i am not able to see my file on the url which i have sent.
curl -s -v --form file=@file3.txt https://URL/upload

@albertogalan
Copy link

albertogalan commented May 18, 2018

I llike it!

@steffanhalv
Copy link

steffanhalv commented Jun 6, 2018

Tried to clear some things up to make it more understandable:

import path from 'path'
import express from 'express'
import formidable from 'formidable'

let app = express()

app.post('/upload', (req, res) => {

  let form = new formidable.IncomingForm()

  /**
   * Options
   */
  form = Object.assign(form, {
    multiples: true,
    keepExtensions: true,
    uploadDir: path.join(__dirname, '../uploads/'), // Set standard upload dir
    encoding: 'utf-8',
    type: 'multipart', // or urlencoded
    maxFieldsSize: 20 * 1024 * 1024, // default = 20 * 1024 * 1024 = 20mb
    maxFields: 1000, // Max files & fields - default = 1000
    hash: false, // sha1, md5 or false
    // @note - Disable field & file event listeners and let you handle upload yourself
    onPart (part) {
      part.addListener('data', packet => {
        // console.log('Packet received', packet.toString()) // Raw packet data
        // packet_a + packet_b + packet_c + ... = file data
      })
      // Handle part / file only if .mov is not included in filename
      if (part.filename && part.filename.indexOf('.mov') === -1) {
        form.handlePart(part)
      // Or if filename is not set
      } else if (!part.filename) {
        form.handlePart(part)
      }
    }
  })

  /**
   * Events
   */
  form.on('fileBegin', (name, file) => {
    // file.name - basename with extension
    // file.size - currently uploaded bytes
    // file.path - beeing written to
    // file.type - mime
    // file.lastModifiedDate - date object or null
    // file.hash - hex digest if set
    // Changing file upload path can also be done here:
    file.path = path.join(__dirname, '../uploads_secondary/' + file.name)
  })
  form.on('progress', (bytesReceived, bytesExpected) => {
    console.log('Progress', bytesReceived, bytesExpected)
  })
  form.on('error', (err) => {
    console.error(err)
  })
  form.on('aborted', () => {
    console.error(new Error('Aborted'))
  })
  form.on('end', () => {
    console.log('End')
  })
  form.on('field', (name, value) => {
    console.log('Field', name, value)
  })
  form.on('file', (name, file) => {
    console.log('File', name, file.type)
  })

  /**
   * Function
   *
   * Passes request from express to formidable for handling.
   * Second arg is a callback executed on complete & returns all data
   *
   */
  form.parse(req, (err, fields, files) => {
    if (err) {
      return res.status(500).json({ error: err })
    } else {
      return res.status(200).json({ uploaded: true })
    }
  })

})

app.listen(4000)

@diasor
Copy link

diasor commented Sep 14, 2018

@cannap super useful

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment