EzDevInfo.com

multer

Node.js middleware for handling `multipart/form-data`.

Multer: how to name files after req.body parameters

I'm trying to upload a file with a form such as below

<input type="file" name="collateral" />
<input type="hidden" name="id" value="ABCDEFG" />
<input type="submit" value="Upload Image" name="submit">

and I would like to rename to file to the name in the id input (ABCDEFG). As I can't access the req.body through the rename: function(fieldname, filename), I was wondering how I would achieve this?


Source: (StackOverflow)

User Multer in Express Route? (Using MEANJS)

I'm using Multer to upload images in Express 4. However, the examples all show Multer being defined in the express file as Middleware. I'd like to actually define some of the Multer behaviors in my app routing itself. Is this possible? The end result that I need is for my route function to recognize when the upload is finished before it sends the server response to the browser, so an image can be displayed to the user (right now I'm only getting a partial image displayed because the file hasn't finished uploading yet).

CURRENT, WORKING CODE

express.js

// Require Multer as module dependency.
var multer = require('multer');

// Using Multer for file uploads.
app.use(multer({
    dest: './public/profile/img/',
    limits: {
        fieldNameSize: 50,
        files: 1,
        fields: 5,
        fileSize: 1024 * 1024
    },
    rename: function(fieldname, filename) {
        return filename;
    },
    onFileUploadStart: function(file) {
        if(file.mimetype !== 'image/jpg' && file.mimetype !== 'image/jpeg' && file.mimetype !== 'image/png') {
            return false;
        }
    }
}));

server_routes.js

app.route('/users/image').post(server_controller_file.imageUpload);

server_controller_file.js

exports.imageUpload = function(req, res) {
// Check to make sure req.files contains a file, mimetypes match, etc., then send appropriate server response.
};

Ideally, my server_controller_file.js would contain some checks to make sure the file finished uploading, e.g. (note: this is hypothetical/desirable, not actual working code)...

var multer = require('multer');
exports.imageUpload = function(req, res) {
    multer({
        onFileUploadComplete: function(file) {
            res.send();
        }
    });
}

Again, right now the async nature of node is causing the browser to think the upload is complete as soon as it receives a successful response, so when I update the url to display the image, it only partially displays. Thanks for the help!


Source: (StackOverflow)

Advertisements

How to set different destinations in nodejs using multer?

I'm trying to upload any file using Multer package. It's working fine when I use following code in my server.js file.

var express = require('express'),
    app = express(),
    multer = require('multer');
app.configure(function () {
    app.use(multer({
        dest: './static/uploads/',
        rename: function (fieldname, filename) {
            return filename.replace(/\W+/g, '-').toLowerCase();
        }
    }));
    app.use(express.static(__dirname + '/static'));
});

app.post('/api/upload', function (req, res) {
    res.send({image: true, file: req.files.userFile.originalname, savedAs: req.files.userFile.name});
});

var server = app.listen(3000, function () {
    console.log('listening on port %d', server.address().port);
});

What I want is to store file at different locations. I had tried following code but it does not work for me.

var express = require('express'),
    app = express(),
    multer = require('multer');
app.configure(function () {
    app.use(multer({
        //dest: './static/uploads/',
        rename: function (fieldname, filename) {
            return filename.replace(/\W+/g, '-').toLowerCase();
        }
    }));
    app.use(express.static(__dirname + '/static'));
});

app.post('/api/pdf', function (req, res) {
    app.use(multer({ dest: './static/pdf/'}));
    res.send({image: true, file: req.files.userFile.originalname, savedAs: req.files.userFile.name});
});

app.post('/api/image', function (req, res) {
    app.use(multer({ dest: './static/image/'}));
    res.send({image: true, file: req.files.userFile.originalname, savedAs: req.files.userFile.name});
});

app.post('/api/video', function (req, res) {
    app.use(multer({ dest: './static/video/'}));
    res.send({image: true, file: req.files.userFile.originalname, savedAs: req.files.userFile.name});
});

var server = app.listen(3000, function () {
    console.log('listening on port %d', server.address().port);
});

Means, if I hit http://localhost:3000/api/pdf file should store at 'pdf' folder, if I hit http://localhost:3000/api/video file should store at 'video' folder.

Is there any way to achieve this aim?

Thank you in advance.


Source: (StackOverflow)

Cannot app.use(multer). "requires middleware function" error

I'm just starting learning NodeJS and I am stuck with a problem. I would like to upload files to my server. To do so I searched and found out this module multer. Doing as the example on GitHub works:

var express = require('express');
var multer = require('multer');
var upload = multer({ dest: 'uploads/' });

var app = express()

app.post('/uploadImage', upload.single('image'), function(req, res) {
    console.log(req.file);
});

On posting an image with FormData to /uploadImage the image is saved in the uploads/ directory. The thing is the image is saved with a strange name and I would like to save it with its original name. To do so I understood that I would have to call app.use(multer({ dest: 'uploads/' }))' and then I would be able to access req.file in my function like:

app.post('/uploadImage', function(req, res) {
    console.log(req.file);
});

But I get an error on trying app.use():

TypeError: app.use() requires middleware functions
    at EventEmitter.use (project\node_modules\express\lib\application
.js:209:11)

Im using NodeJS 0.12.7 and Express 4.13.1

How can I achieve that upload? Thanks.


Source: (StackOverflow)

NodeJS upload files 100% cpu usage

I've tried two different libraries: multer and formidable for handling file upload in node and both of them use 100% CPU during upload.

Is it a common node problem? And how people deal with it in high concurrency environment?

Node version: v0.10.36 (I've even tried other versions like v0.11.x or v0.10.33)

Formidable example

Picture.upload = function(user, req, cb) {
    var formidable = require('formidable')

    var form = new formidable.IncomingForm();
    form.uploadDir = "./uploads";
    form.maxFieldsSize = app.settings.uploadMaxSize * 1024 * 1024;
    form.maxFields = 1000;

    form.parse(req, function(err, fields, files) {
        cb(null, files);
    });
}

Multer example

app.use(multer({ dest: './uploads/',
    rename: function (fieldname, filename) {
       return filename+Date.now();
    },
    limits: {
       files: 1,
       fileSize: app.settings.uploadMaxSize * 1024 * 1024
    }
})); // after I process the file from req.files

File are uploaded as multipart/form-data.

I'm using loopback, but I don't think it makes any difference.


Source: (StackOverflow)

multer configuration with app.use returns TypeError

I'm trying to configure multer in my app.js file (using node.js/express) in order to allow users to upload images. I have the following code in app.js:

//various require statements for passport, cookie parser, etc..

var multer = require('multer');

var app = express();

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

When I try to run the app I get TypeError: app.use() requires middleware functions

I understand that this questions may require some more context with regards to my app so please let me know if additional information is needed.

Thank you

EDIT: More code from app.js:

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var session = require('express-session');
//var fs = require('fs');
var multer = require('multer');

//Mongo Database
var mongo = require('mongodb');
var monk = require('monk');
var db = monk('localhost:27017/test-api');

//Instagram-API
var api = require('instagram-node').instagram();

//Cookie Manager
var cookieParser = require('cookie-parser');

//Grid
//var Grid = require('gridfs-stream');

//Passport
var passport = require('passport');
var InstagramStrategy = require('passport-instagram').Strategy;

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', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(multer({dest:'./uploads/'}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(methodOverride());
app.use(session({secret: 'keyboard cat', resave: false, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static(path.join(__dirname, 'public')));


// Make our db accessible to our router
app.use(function(req,res,next){
    req.db = db;
    next();
});

app.use('/', routes);

Source: (StackOverflow)

How to send response to client when files is too large with Multer

I'm using NodeJs Multer to upload files. I need to send response back to a client when file user tries to upload is too large. The problem is that onFileSizeLimit only has file as argument and I dont know how to send response to client. What I need to do is basically soomething like below:

app.use('/users/gyms/upload-logo', multer({
    // other settings here then:
    onFileSizeLimit: function (file) {
        // but res (response) object is not existing here
        res.json({
            message: "Upload failed",
            status: MARankings.Enums.Status.FILE_TOO_LARGE
            // status: -6
        });
    }
});

res object dosent exists in there however and I'm wondering what is the best way to send some sort of response to client.


Source: (StackOverflow)

Reading contents of csv file in node.js

I am trying to implement a module in nodejs(just started working in nodejs) which has requirement below as

  1. Upload .csv file.
  2. Read content of the csv file.

Frameworks currently being used for restful api is "express": "~4.2.0" and multer for file upload.

Now I have configured multer like below in my app.js

app.use(multer({
  onFileUploadData : function(file, data){
    console.log('onFileUploadData Called with data - '+ data);
  }
}));

In my route file, I have a post endpoint like below

app.post('/sample.csv',lead.processCSV);

This route is being called from an ajax call below as

$.ajax({
            xhrFields: {withCredentials: true},
            url: '/sample.csv',
            type: 'POST',
            success: function (data) {
                $scope.handleResponse(data);
            },
            error: function (error, xhr) {
                angular.element('#csvUploadBusyIcon').hide();
                alert('Oops! Upload failed');
            },
            data: formData,
            cache: false,
            contentType: false,
            processData: false
        });

Now I want to get the content of the csv file, i.e. when all the content has been loaded then I should handle my lead.processCSV method.

Also do I need any other module for csv files, or multer is sufficient in my case?

Any suggestion/guidance in right direction will be helpful. Thanks in Advance.


Source: (StackOverflow)

Node.js and Multer - Handle the destination of the uploaded file in callback function (req,res)

i'm a newbie in Node.js and i have run into a very simple problem lately.

I'm using a module named multer, so users can upload images. In my web app all the users have a unique id, and i want the uploaded images to be stored in a directory named based on their id.

Example:

.public/uploads/3454367856437534

Here is a part of my routes.js file:

// load multer to handle image uploads
var multer  = require('multer');
var saveDir = multer({
  dest: './public/uploads/' + req.user._id, //error, we can not access this id from here
  onFileUploadStart: function (file) { 
  return utils.validateImage(file); //validates the image file type
  }
});

module.exports = function(app, passport) {

app.post('/', saveDir, function(req, res) {
                id     : req.user._id,  //here i can access the user id
    });
});

}

How can i access the

req.user._id 

outside of the

function(req,res)

So i can use it with multer to generate the proper directory based on the id?

EDIT Here is what i have tried and didn't work:

module.exports = function(app, passport) {

app.post('/', function(req, res) {
    app.use(multer({
        dest: './public/uploads/' + req.user._id
    }));
});

}

Source: (StackOverflow)

Express.js and multer: how to know when the files are all uploaded?

I'm using Multer module for file uploads. While it all works ok, there's a warning at the end of their github page, which reads: "WARNING: req.body is fully parsed after file uploads have finished. Accessing req.body prematurely may cause errors."

This has got me really worried. I just can't find a way to let the .post middleware know when the file(s) have been uploaded and req.body is ready to use. Here's my code:

app.js:

app.use(multer({ 
        dest: './uploads/',
        rename: function (fieldname, filename) {
            return filename.replace(/\W+/g, '-').toLowerCase() + Date.now();
        },
        putSingleFilesInArray: true       
        })
);

upload.js:

router.route('/')
    .get(function(req, res){
        res.render('uploads');
    })
    .post(function(req, res){
        //how to wait here for the file to upload?
    });

While I am aware of onParseEnd, but I don't know how to implement it, so that I have at least some kind of information about the upload process being finished.


Source: (StackOverflow)

Node Multer unexpected field

I'm working on uploading a file to my app using the multer npm module.

The multer function I have defined is to allow a single file uploaded to the file system. Everything works during run time; the issue is after I upload the file I get an error below. Any advice appreciated on where to look.

Error:

Unexpected field

Error: Unexpected field
    at makeError (c:\Users\Dev\WebstormProjects\Crunch\node_modules\multer\lib\make-error.js:12:13)
    at wrappedFileFilter (c:\Users\Dev\WebstormProjects\Crunch\node_modules\multer\index.js:39:19)
    at Busboy.<anonymous> (c:\Users\Dev\WebstormProjects\Crunch\node_modules\multer\lib\make-middleware.js:97:7)
    at Busboy.emit (events.js:118:17)
    at Busboy.emit (c:\Users\Dev\WebstormProjects\Crunch\node_modules\multer\node_modules\busboy\lib\main.js:31:35)
    at PartStream.<anonymous> (c:\Users\Dev\WebstormProjects\Crunch\node_modules\multer\node_modules\busboy\lib\types\multipart.js:205:13)
    at PartStream.emit (events.js:107:17)
    at HeaderParser.<anonymous> (c:\Users\Dev\WebstormProjects\Crunch\node_modules\multer\node_modules\busboy\node_modules\dicer\lib\Dicer.js:51:16)
    at HeaderParser.emit (events.js:107:17)
    at HeaderParser._finish (c:\Users\Dev\WebstormProjects\Crunch\node_modules\multer\node_modules\busboy\node_modules\dicer\lib\HeaderParser.js:70:8) 

app.js

var multer = require('multer');
var app = express();
var fs = require('fs');

//. . . 

var upload = multer({ dest: 'upload/'});
var type = upload.single('file');

app.post('/upload', type, function (req,res) {
  var tmp_path = req.files.recfile.path;
  var target_path = 'uploads/' + req.files.recfile.name;
fs.readFile(tmp_path, function(err, data)
{
  fs.writeFile(target_path, data, function (err)
  {
    res.render('complete');
  })
});

Index.hbs

<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name='recfile' placeholder="Select file"/>
    <br/>
    <button>Upload</button>
</form>

#Package.json
  "dependencies": {
    "body-parser": "~1.13.2",
    "cookie-parser": "~1.3.5",
    "debug": "~2.2.0",
    "easy-zip": "0.0.4",
    "express": "~4.13.1",
    "hbs": "~3.1.0",
    "less-middleware": "1.0.x",
    "morgan": "~1.6.1",
    "multer": "~1.0.0",
    "serve-favicon": "~2.3.0"
  }
}

Source: (StackOverflow)

Decide the upload folder location of Multer middleware

All:

I am new to Express.js, when I deal with file uploading with Multer (https://github.com/expressjs/multer), I specify a multer middleware object:

var upload = multer({dest: 'uploads/'});

But one thing confuse me so much is: No matter where I put this line code( either in sub router file, or app.js), it always creates "uploads" folder under project root( same folder with app.js, views, routes, public... located), even I change it to "./uploads/", it still creates uploads folder under project root.

This confuses me so much, cos when I compare this with require() function, it seems require() uses relative path based on where it is get called while multer is not? I wonder if my understand is correct? And how to change it to relative if mine is correct?

Thanks


Source: (StackOverflow)

What is wrong with Nodejs?

I am using multer to handle upload image.

app.use(multer({ dest: './public/photos',
    rename: function (fieldname, filename) {
        return filename+Date.now();
    },
    onFileUploadStart: function (file) {
        console.log(file.originalname + ' is starting ...')
    },
    onFileUploadComplete: function (file) {
        console.log(file.fieldname + ' uploaded to  ' + file.path)
        //a='asass';
        done=true;
    }
}));

app.post('/api/photo',function(req,res){
  if(done==true){ //ERROR here if I remove comment on 'a=asass' >> 'done' is not defined
    console.log(req.files);
    console.log(req.body);
    res.end("File uploaded.");
  }
});

I do NOT declare "done" variable anywhere, why this code still works?. If I remove comment on "a = asass" I get the err at above. (I do NOT declare "a" variable anywhere). I should get the error when I assign value to variables, but it does not happen.


Source: (StackOverflow)

NodeJS: server responds extremely slowly while uploading 5+ photos

When I'm uploading more than 5 photos at same time (5 multipart/form-data request), during its process, any GET request has ~500ms delay, any Socket.io event has ~1500ms delay.

Is this normal? I tried with Multer and Multiparty as upload middleware, both give the same lag.

The photos are each about 5MB large. The CPU usage for of node process during the upload raises about 5% than average, and memory usage stays normal.

Server: Hosted on DigitalOcean. Ubuntu with 1G RAM, 1 Core Processor, 30G SSD

Does anyone experience the same thing? Here's a snippet for Multer. I would really appreciate for any help, I've been trying to solve this for 5 days now without any success :(

function photoUpload(req, res, next){
    dest: 'public/photos',
    limits: { fileSize: 10*1000000 }, // 10MB file limit
    onFileSizeLimit: function (file) { fs.unlink(file.path) },
    onParseEnd: function (req, next) { 
        var file = req.files.photo;
        file.url = '/photos/' + file.name; // save photo url
        next(); 
    }
}

app.post('/api/upload', photoUpload, function(req, res){
    Database.createPhoto(req.file.url); // save photo url in database
});

Source: (StackOverflow)

Passing data from server/app.js to controller Angular-fullstack + multer

I'm struggling to get a filename passed from server/app.js to a controller in client/app/

I am using Multer to deal with the file upload which is working fine but i need to pass the filename back to the client to display it in the next view.

Here is the code i have:

server/app.js

app.use(multer({ dest: 'client/assets/uploads',
 rename: function (fieldname, filename) {
    return filename+Date.now();
  },
    onFileUploadStart: function (file) {
      console.log(file.originalname + ' is starting ...')
    },
    onFileUploadComplete: function (file) {
      console.log(file.fieldname + ' uploaded to  ' + file.path)
      done=true;
    }
}));


app.post('/api/photo',function(req,res){
  if(done==true){
    photoName = req.files.userPhoto.name;
    res.json(photoName);
  }
});

It's showing the new filename but i need it to be in a usable form and as i'm doing all this server side i have nothing in my controller to handle the incoming response.

Any help would be greatly appreciated.


Source: (StackOverflow)