Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node/Express file upload

I'm using node v0.10.26 and express v4.2.0 and I'm pretty new to node. I've been beating my head against my desk for the past three or so hours trying to get a file upload form working with node. At this point I'm just trying to get req.files to not return undefined. My view looks like this

<!DOCTYPE html> <html> <head>   <title>{{ title }}</title>   <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body>   <h1>{{ title }}</h1>   <p>Welcome to {{ title }}</p>   <form method='post' action='upload' enctype="multipart/form-data">     <input type='file' name='fileUploaded'>     <input type='submit'>   </form> </body> </html> 

Here are my routes

var express = require('express'); var router = express.Router();   /* GET home page. */ router.get('/', function(req, res) {   res.render('index', { title: 'Express' }); });  router.post('/upload', function(req, res){ console.log(req.files); });  module.exports = router; 

And here's my app.js

var express = require('express'); var path = require('path'); var favicon = require('static-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser');  var routes = require('./routes/index'); var users = require('./routes/users');  var app = express();  // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'hjs');  app.use(favicon()); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded()); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public')));  app.use('/', routes); app.use('/users', users);  /// catch 404 and forward to error handler app.use(function(req, res, next) {     var err = new Error('Not Found');     err.status = 404;     next(err); });  /// error handlers  // development error handler // will print stacktrace if (app.get('env') === 'development') {     app.use(function(err, req, res, next) {         res.status(err.status || 500);         res.render('error', {             message: err.message,             error: err         });     }); }  // production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) {     res.status(err.status || 500);     res.render('error', {         message: err.message,         error: {}     }); });    module.exports = app; 

I saw somewhere that including methodOverride() and bodyParser({keepExtensions:true,uploadDir:path}) was supposed to help but I can't even launch my server if I add those lines.

like image 445
okawei Avatar asked May 16 '14 01:05

okawei


People also ask

How do I upload files to node JS Express server using Express fileUpload library?

Create Express Server const express = require('express'); const fileUpload = require('express-fileupload'); const cors = require('cors'); const bodyParser = require('body-parser'); const morgan = require('morgan'); const _ = require('lodash'); const app = express(); // enable files upload app.

Can I upload files to MongoDB?

Step 3: Storing Your Files in MongoDB through GridFS. By default, MongoDB only allows you to upload files below 16MB.


2 Answers

ExpressJS Issue:

Most of the middleware is removed from express 4. check out: http://www.github.com/senchalabs/connect#middleware For multipart middleware like busboy, busboy-connect, formidable, flow, parted is needed.

This example works using connect-busboy middleware. create /img and /public folders.
Use the folder structure:

\server.js

\img\"where stuff is uploaded to"

\public\index.html

SERVER.JS

var express = require('express');    //Express Web Server  var busboy = require('connect-busboy'); //middleware for form/file upload var path = require('path');     //used for file path var fs = require('fs-extra');       //File System - for file manipulation  var app = express(); app.use(busboy()); app.use(express.static(path.join(__dirname, 'public')));  /* ==========================================================  Create a Route (/upload) to handle the Form submission  (handle POST requests to /upload) Express v4  Route definition ============================================================ */ app.route('/upload')     .post(function (req, res, next) {          var fstream;         req.pipe(req.busboy);         req.busboy.on('file', function (fieldname, file, filename) {             console.log("Uploading: " + filename);              //Path where image will be uploaded             fstream = fs.createWriteStream(__dirname + '/img/' + filename);             file.pipe(fstream);             fstream.on('close', function () {                     console.log("Upload Finished of " + filename);                               res.redirect('back');           //where to go next             });         });     });  var server = app.listen(3030, function() {     console.log('Listening on port %d', server.address().port); }); 

INDEX.HTML

<!DOCTYPE html> <html lang="en" ng-app="APP"> <head>     <meta charset="UTF-8">     <title>angular file upload</title> </head>  <body>         <form method='post' action='upload' enctype="multipart/form-data">         <input type='file' name='fileUploaded'>         <input type='submit'>  </body> </html> 

The following will work with formidable SERVER.JS

var express = require('express');   //Express Web Server  var bodyParser = require('body-parser'); //connects bodyParsing middleware var formidable = require('formidable'); var path = require('path');     //used for file path var fs =require('fs-extra');    //File System-needed for renaming file etc  var app = express(); app.use(express.static(path.join(__dirname, 'public')));  /* ==========================================================   bodyParser() required to allow Express to see the uploaded files ============================================================ */ app.use(bodyParser({defer: true}));  app.route('/upload')  .post(function (req, res, next) {    var form = new formidable.IncomingForm();     //Formidable uploads to operating systems tmp dir by default     form.uploadDir = "./img";       //set upload directory     form.keepExtensions = true;     //keep file extension      form.parse(req, function(err, fields, files) {         res.writeHead(200, {'content-type': 'text/plain'});         res.write('received upload:\n\n');         console.log("form.bytesReceived");         //TESTING         console.log("file size: "+JSON.stringify(files.fileUploaded.size));         console.log("file path: "+JSON.stringify(files.fileUploaded.path));         console.log("file name: "+JSON.stringify(files.fileUploaded.name));         console.log("file type: "+JSON.stringify(files.fileUploaded.type));         console.log("astModifiedDate: "+JSON.stringify(files.fileUploaded.lastModifiedDate));          //Formidable changes the name of the uploaded file         //Rename the file to its original name         fs.rename(files.fileUploaded.path, './img/'+files.fileUploaded.name, function(err) {         if (err)             throw err;           console.log('renamed complete');           });           res.end();     }); }); var server = app.listen(3030, function() { console.log('Listening on port %d', server.address().port); }); 
like image 128
Mick Cullen Avatar answered Sep 26 '22 02:09

Mick Cullen


Another option is to use multer, which uses busboy under the hood, but is simpler to set up.

var multer = require('multer'); 

Use multer and set the destination for the upload:

app.use(multer({dest:'./uploads/'})); 

Create a form in your view, enctype='multipart/form-data is required for multer to work:

form(role="form", action="/", method="post", enctype="multipart/form-data")     div(class="form-group")         label Upload File         input(type="file", name="myfile", id="myfile") 

Then in your POST you can access the data about the file:

app.post('/', function(req, res) {   console.dir(req.files); }); 

A full tutorial on this can be found here.

like image 37
Carasel Avatar answered Sep 24 '22 02:09

Carasel