Upload file with node.js, get more than one file - node.js

I have this code in order to upload single file with node.js, using express and multer:
var express = require("express");
var app = express();
var fs = require("fs");
var multer = require('multer');
var upload = multer({ dest: 'uploads/' });
// Process upload file
app.post('/file_upload', upload.single('single-file'), function(request, response) {
var fileName = request.file.originalname;
var filePath = request.file.path;
var file = __dirname + "/uploads/" + fileName;
fs.readFile(filePath, function(err, data) {
fs.writeFile(file, data, function(err) {
if (err) {
console.log(err);
} else {
responseData = {
'message' : 'File uploaded successfully',
'fileName' : fileName
};
}
response.end(JSON.stringify(responseData));
})
});
});
Here is the HTML file:
<!DOCTYPE html>
<html>
<head>
<title>File Uploading Form</title>
</head>
<body>
<h3>File Upload:</h3>
Select a file to upload: <br />
<form action="http://localhost:8081/file_upload" method="POST"
enctype="multipart/form-data">
<input type="file" name="single-file" size="50" />
<br />
<input type="submit" value="Upload File" />
</form>
</body>
</html>
After running the code, I was able to uploaded file.
But the problem is, I keep getting 2 files uploaded in my "uploads" folder each time. One file with the original name, and one with strange name like 2787ab2db292d90bd2da83a6a6ce1700.
Is that normal? How can I get rid of the other file when upload?

the problem is You're creating new file from already uploaded file.
so solution is to rename uploaded file with temporary name to original name:
var express = require("express");
var app = express();
var fs = require("fs");
var multer = require('multer');
var uploadsFolder = __dirname + '/uploads/'; // defining real upload path
var upload = multer({ dest: uploadsFolder }); // setting path for multer
// Process upload file
app.post('/file_upload', upload.single('single-file'), function(request, response) {
var fileName = request.file.originalname; // original file name
var file = request.file.path; // real file path with temporary name
// renaming real file to it's original name
fs.rename(file, uploadsFolder + fileName, function (err) {
if (err) {
console.log(err);
response.json({success:false, message: err});
return;
}
response.json({success:true, message: 'File uploaded successfully', fileName: fileName});
});
});
or make multer to upload to temporary folder and then copy or move to uploads folder:
install fs extra:
npm install --save fs.extra
and
var express = require("express");
var app = express();
var fs = require('fs.extra'); // extra functionality
var multer = require('multer');
var uploadsFolder = __dirname + '/uploads/'; // defining real upload path
var tempFolder = __dirname + '/tmp/'; // folder for temporary files, must exist
var upload = multer({ dest: tempFolder }); // setting path for multer
// Process upload file
app.post('/file_upload', upload.single('single-file'), function(request, response) {
var fileName = request.file.originalname; // original file name
var file = request.file.path; // real file path with temporary name
// renaming real file to it's original name
fs.move(file, uploadsFolder + fileName, function (err) {
if (err) {
console.log(err);
response.json({success:false, message: err});
return;
}
response.json({success:true, message: 'File uploaded successfully', fileName: fileName});
});
});

Related

Can't change destination in multer

When i upload my form (which just contains an image), the image goes in the root folder, but I would like it to go to /public/images. I have a separate routes.js file to handle routes. This is how I've set up multer (in my routes.js file).
var multer = require('multer');
var upload = multer({dest: '/public'});
The route for the POST request looks like this:
app.post('/upload', isLoggedIn, upload.single('file'), function (req, res) {
var file = __dirname + req.file.filename;
fs.rename(req.file.path, file, function (err) {
if (err) {
console.log(err);
res.send(500);
} else {
res.json({
message: 'File uploaded successfully',
filename: req.file.filename
});
console.log(file);
}
});
});
, and the form itself looks like this (it's an ejs file):
<form method="post" action="/upload" enctype="multipart/form-data">
<label for="profilepicture">Profile picture</label>
<input type="file" name="file" accept="image/*">
<input type="submit" value="change profile picture">
</form>
You are providing a wrong path in the dest, it's a relative path so it should be dest: 'public/' instead of dest: '/public'
Also, you are moving the file from the public folder by using fs.rename and the reason it is moved to outside the root folder is you are adding the root folder in the filename and not as a path :
var file = __dirname + req.file.filename;
should be :
var file = __dirname + '/' + req.file.filename;
or even better :
var file = path.join(__dirname, req.file.filename);
Overall, a working script with no need for the fs.rename :
var multer = require('multer');
var upload = multer({dest: 'public/'});
app.post('/upload', isLoggedIn, upload.single('file'), function (req, res) {
res.json({
message: 'File uploaded successfully',
filename: req.file.filename
})
})

Error uploading files using Multer in NodeJs

I am trying to write an Express-based API for uploading files. The filename and directory path should be set dynamically.
My code:
var crypto = require('crypto')
var express = require('express');
var fs = require('fs');
var mime = require('mime');
var mkdirp = require('mkdirp');
var multer = require('multer');
var app = express();
var path = './uploads';
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, path);
console.log('Im in storage destination'+path);
},
filename: function (req, file, callback) {
console.log('Im in storage filename'+path);
//callback(null, file.fieldname + '-' + Date.now());
crypto.pseudoRandomBytes(16, function (err, raw) {
callback(null, Date.now() + '.' + mime.extension(file.mimetype));
});
}
});
var upload = multer({ storage : storage}).single('userPhoto');
app.post('/photo',function(req,res){
path += '/pics/shanmu/';
console.log('Im in post , outside upload'+path);
upload(req,res,function(err) {
console.log('Im in post , inside upload'+path);
if(err) {
return res.end('Error uploading file.');
}
res.end('File is uploaded'+path);
console.log('File is uploaded'+path);
});
});
app.listen(3000,function(){
console.log('Working on port 3000');
});
My folder structure:
When I run the code, the file should be uploaded in the uploads/ folder. (This folder has two nested folders inside it - uploads/pics/shanmu).
When I triggered it from postman, it only works once. When I try the second time, I cannot upload files.
Please advise.
Working on sometime I got a solution using multer module.Using this module you can upload both files and images.And it successfully uploaded to the destination folder.
Here is my server code app.js
var express =r equire('express');
var multer = require('multer');
var path = require('path')
var app = express();
var ejs = require('ejs')
app.set('view engine', 'ejs')
var storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, './public/uploads')//here you can place your destination path
},
filename: function(req, file, callback) {
callback(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
}
})
app.get('/api/file',function(req,res){
res.render('index');
});
app.post('/api/file', function(req, res) {
var upload = multer({
storage: storage}).single('userFile');
upload(req, res, function(err) {
console.log("File uploaded");
res.end('File is uploaded')
})
})
app.listen(3000,function(){
console.log("working on port 3000");
});
Create a views folder and place this index.ejs file in it
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form id="uploadForm" enctype="multipart/form-data" method="post">
<input type="file" name="userFile" />
<input type="submit" value="Upload File" name="submit">
</form>
</body>
</html>
After this run the server as node app.js.Open the browser and type http://localhost:3000/api/file after runnig this url choose a file which you want to upload to destination folder.And have a successfull response in both terminal and browser.Hope this helps for you.
I got your code working. See:
https://gist.github.com/lmiller1990/3f1756efc07e09eb4f44e20fdfce30a4
I think the problem was with the way you declared destination. I'm not sure why, though. I got it working by just passing the path as a string.
Best of luck!

How to access uploaded file from multer?

Im able to upload an image to S3. Now, if the file selected is .gif, I want to be able to convert the .gif file to .mp4 and upload the converted file to S3. I am able to convert a .gif to .mp4 with ffmpeg only if I give the path of the file. How do I access the uploaded file from Multer? Below is my code :
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var aws = require('aws-sdk');
var multer = require('multer');
var multerS3 = require('multer-s3');
var s3 = new aws.S3();
var ffmpeg = require('fluent-ffmpeg');
var upload = multer({
storage: multerS3({
s3: s3,
bucket: 'myBucket',
key: function (req, file, cb) {
console.log(file);
var extension = file.originalname.substring(file.originalname.lastIndexOf('.')+1).toLowerCase();
if(extension=="gif"){
console.log("Uploaded a .gif file");
ffmpeg(file) //THIS IS NOT WORKING
.setFfmpegPath("C:\\ffmpeg\\bin\\ffmpeg.exe")
.output('./outputs/2.mp4') //TRYING TO UPLOAD LOCALLY, WHICH FAILS
.on('end', function() {
console.log('Finished processing');
})
.run();
}
cb(null, filename);
}
})
});
I'm trying to access the uploaded file like this: ffmpeg(file) since file is an argument passed in the multer function.
My form :
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file"> <br />
<input type="submit" value="Upload">
</form>
In which part of the process do I convert the file?
Please help. Many thanks.
You are trying to process a file locally that's on s3. The file needs to be your server's file system or at the very least be publicly available on s3. So you have two options here.
a) You could first upload all the files to the server where express is running (not on s3, first we store them temporarily). If the file is a .gif, process it and upload the resulting .mp4 file, otherwise upload to s3. Here's a working example:
var fs = require('fs')
var path = require('path')
var express = require('express');
var bodyParser = require('body-parser');
var aws = require('aws-sdk');
var multer = require('multer');
var ffmpeg = require('fluent-ffmpeg');
var shortid = require('shortid');
aws.config.update(/* your config */);
var app = express();
var s3 = new aws.S3();
var bucket = 'myBucket';
var upload = multer({
storage: multer.diskStorage({
destination: './uploads/',
filename: function (req, file, cb){
// user shortid.generate() alone if no extension is needed
cb( null, shortid.generate() + path.parse(file.originalname).ext);
}
})
});
//----------------------------------------------------
app.post('/upload', upload.single('file'), function (req, res, next) {
var fileInfo = path.parse(req.file.filename);
if(fileInfo.ext === '.gif'){
var videoPath = 'uploads/' + fileInfo.name + '.mp4';
ffmpeg(req.file.path)
.setFfmpegPath("C:\\ffmpeg\\bin\\ffmpeg.exe")
.output(videoPath)
.on('end', function() {
console.log('[ffmpeg] processing done');
uploadFile(videoPath, fileInfo.name + '.mp4');
})
.run();
}
else {
uploadFile(req.file.path, req.file.filename);
}
res.end();
});
//----------------------------------------------------
function uploadFile(source, target){
fs.readFile(source, function (err, data) {
if (!err) {
var params = {
Bucket : bucket,
Key : target,
Body : data
};
s3.putObject(params, function(err, data) {
if (!err) {
console.log('[s3] file uploaded:');
console.log(data);
fs.unlink(source); // optionally delete the file
}
else {
console.log(err);
}
});
}
});
}
app.listen(3000);
b) Alternatively if you're ok with making your s3 files public you could upload them all using multer-s3. Since ffmpeg also accepts network locations as input paths you can pass it the s3 location of your .gif files and then upload the converted .mp4 files:
var fs = require('fs')
var path = require('path')
var express = require('express');
var bodyParser = require('body-parser');
var aws = require('aws-sdk');
var multer = require('multer');
var ffmpeg = require('fluent-ffmpeg');
var multerS3 = require('multer-s3');
aws.config.update(/* your config */);
var app = express();
var s3 = new aws.S3();
var bucket = 'myBucket';
var upload = multer({
storage: multerS3({
s3: s3,
bucket: bucket,
key: function (req, file, cb) {
cb(null, file.originalname);
},
acl: 'public-read'
})
});
----------------------------------------------------
app.post('/upload', upload.single('file'), function (req, res, next) {
var fileInfo = path.parse(req.file.originalname);
if(fileInfo.ext === '.gif'){
var videoPath = 'uploads/' + fileInfo.name + '.mp4';
ffmpeg(req.file.location)
.setFfmpegPath("C:\\ffmpeg\\bin\\ffmpeg.exe")
.output(videoPath)
.on('end', function() {
console.log('[ffmpeg] processing done');
uploadFile(videoPath, fileInfo.name + '.mp4');
})
.run();
}
res.end();
})
//----------------------------------------------------
function uploadFile(source, target){
fs.readFile(source, 'base64', function (err, data) {
if (!err) {
var params = {
Bucket : bucket,
Key : target,
Body : data,
ContentType : 'video/mp4'
};
s3.putObject(params, function(err, data) {
if (!err) {
console.log('[s3] file uploaded:');
console.log(data);
fs.unlink(source); // optionally delete the file
}
else {
console.log(err);
}
});
}
});
}
app.listen(3000);
For both examples, remember to create an uploads/ folder and use your aws configuration.

File upload in node.js

I want to upload my file in my workspace and read it in node.js.
Html code:
<html>
<head>
<script src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body>
<div ng-app="" ng-controller="SalesImportControl">
<form ng-submit="readCustomer()">
<input type="file" name="file" file-model = "myFile">
<br>
<button type="submit" >Submit</button>
</form>
</div>
</body>
</html>
Controller:
'use strict';
angular.module('app')
.controller('SalesImportControl', ['$scope','$http', '$location', '$rootScope','fileUpload' , function($scope, $http, $location, $rootScope,fileUpload) {
console.log(" In dataimportCtrl");
//customer
$scope.readCustomer = function(req,res){
var file1=$scope.myFile;
var fl1 = $scope.myFile.name;
console.log("file name:"+$scope.myFile.name);
var uploadUrl = "/fileUpload";
var fd = new FormData();
fd.append('file', file1);
//File upload
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
}).success(function(data){
}).error(function(){
});
//sales
$http.post('/salesimport', { params: fl1 }).success(function(data) {
console.log("in controller1");
console.log("controller:"+data);
$scope.data=data["jarr"];
$scope.data1=data["jarr1"];
$scope.data2=data["jarr2"];
$scope.data3=data["jarr3"];
$scope.data4=data["jarr4"];
}).error(function(response) {
console.error("error in posting");
});
};
}])
Server.js:
var express = require('express');
var bodyparser = require('body-parser');
var mysql = require('mysql');
var app = express();
var formidable = require('formidable');
var path = require('path');
var fs = require('fs');
var _ = require('underscore');
var vouchersmodel = require('./models/v_db.js');
app.use(express.static(__dirname + "/public/angular"));
app.use(bodyparser.json());
app.listen(3000);
console.log('Server running on 3000');
app.post('/fileUpload', function (req, res) {
var form = new formidable.IncomingForm();
//Formidable uploads to operating systems tmp dir by default
form.uploadDir = __dirname+"/models/upload2/"; //set upload directory
form.keepExtensions = true; //keep file extension
form.parse(req, function(err, fields, files) {
res.writeHead(200, {'content-type': 'text/xml'});
res.write('received upload:\n\n');
console.log("form.bytesReceived");
console.log("file size: "+JSON.stringify(files.file.size));
console.log("file path: "+JSON.stringify(files.file.path));
console.log("file name: "+JSON.stringify(files.file.name));
console.log("file type: "+JSON.stringify(files.file.type));
console.log("astModifiedDate:"+JSON.stringify(files.file.lastModifiedDate));
console.log("file:"+JSON.stringify(files.file));
vouchersmodel.upload(files.file.path,files.file.name, function (msg) {
return res.json(msg);
});
});
});
Model:
exports.upload= function(r,name,callback){
var fs = require('fs');
var newPath = __dirname + "/upload2/"+name;
fs.readFile(r, function (err, data) {
fs.writeFile(newPath,data, function (err,res) {
if(!err){
console.log("uploaded.........");
callback();
}
});
});
}
My question is it uploads the file but before uploading the file it runs the salesimport post method in controller and shows no such directory error.
Where I am wrong ?
Note:
salesimport post method request accesses the file uploaded in model.

Uploading images using Node.js, Express, and Mongoose

Please consider newer answers that have more up-to-date information as things have changed over the years!
Since many new Node.js libraries are quickly being rendered obsolete and there are relatively few examples anyways I want to ask about uploading images using:
Node.js (v0.4.1)
Express (1.0.7)
Mongoose (1.1.0).
How have others done it?
I've found: node-formidable, but I am new to uploading images in general so I want to learn general stuff and ways of doing so using Node.js and Express.
I'll answer my own question for the first time. I found an example straight from the source. Please forgive the poor indentation. I wasn't sure how to indent properly when copying and pasting. The code comes straight from Express multipart/form-data example on GitHub.
// Expose modules in ./support for demo purposes
require.paths.unshift(__dirname + '/../../support');
/**
* Module dependencies.
*/
var express = require('../../lib/express')
, form = require('connect-form');
var app = express.createServer(
// connect-form (http://github.com/visionmedia/connect-form)
// middleware uses the formidable middleware to parse urlencoded
// and multipart form data
form({ keepExtensions: true })
);
app.get('/', function(req, res){
res.send('<form method="post" enctype="multipart/form-data">'
+ '<p>Image: <input type="file" name="image" /></p>'
+ '<p><input type="submit" value="Upload" /></p>'
+ '</form>');
});
app.post('/', function(req, res, next){
// connect-form adds the req.form object
// we can (optionally) define onComplete, passing
// the exception (if any) fields parsed, and files parsed
req.form.complete(function(err, fields, files){
if (err) {
next(err);
} else {
console.log('\nuploaded %s to %s'
, files.image.filename
, files.image.path);
res.redirect('back');
}
});
// We can add listeners for several form
// events such as "progress"
req.form.on('progress', function(bytesReceived, bytesExpected){
var percent = (bytesReceived / bytesExpected * 100) | 0;
process.stdout.write('Uploading: %' + percent + '\r');
});
});
app.listen(3000);
console.log('Express app started on port 3000');
Since you're using express, just add bodyParser:
app.use(express.bodyParser());
then your route automatically has access to the uploaded file(s) in req.files:
app.post('/todo/create', function (req, res) {
// TODO: move and rename the file using req.files.path & .name)
res.send(console.dir(req.files)); // DEBUG: display available fields
});
If you name the input control "todo" like this (in Jade):
form(action="/todo/create", method="POST", enctype="multipart/form-data")
input(type='file', name='todo')
button(type='submit') New
Then the uploaded file is ready by the time you get the path and original filename in 'files.todo':
req.files.todo.path, and
req.files.todo.name
other useful req.files properties:
size (in bytes)
type (e.g., 'image/png')
lastModifiedate
_writeStream.encoding (e.g, 'binary')
You can configure the connect body parser middleware in a configuration block in your main application file:
/** Form Handling */
app.use(express.bodyParser({
uploadDir: '/tmp/uploads',
keepExtensions: true
}))
app.use(express.limit('5mb'));
See, the best thing you can do is to just upload the image to the disk and save the URL in MongoDB. Rest when you retrieve the image again. Just specify the URL, and you will get an image. The code for uploading is as follows.
app.post('/upload', function(req, res) {
// Get the temporary location of the file
var tmp_path = req.files.thumbnail.path;
// Set where the file should actually exists - in this case it is in the "images" directory.
target_path = '/tmp/' + req.files.thumbnail.name;
// Move the file from the temporary location to the intended location
fs.rename(tmp_path, target_path, function(err) {
if (err)
throw err;
// Delete the temporary file, so that the explicitly set temporary upload dir does not get filled with unwanted files.
fs.unlink(tmp_path, function() {
if (err)
throw err;
//
});
});
});
Now save the target path in your MongoDB database.
Again, while retrieving the image, just extract the URL from the MongoDB database, and use it on this method.
fs.readFile(target_path, "binary", function(error, file) {
if(error) {
res.writeHead(500, {"Content-Type": "text/plain"});
res.write(error + "\n");
res.end();
}
else {
res.writeHead(200, {"Content-Type": "image/png"});
res.write(file, "binary");
}
});
Try this code.It will help.
app.get('/photos/new', function(req, res){
res.send('<form method="post" enctype="multipart/form-data">'
+ '<p>Data: <input type="filename" name="filename" /></p>'
+ '<p>file: <input type="file" name="file" /></p>'
+ '<p><input type="submit" value="Upload" /></p>'
+ '</form>');
});
app.post('/photos/new', function(req, res) {
req.form.complete(function(err, fields, files) {
if(err) {
next(err);
} else {
ins = fs.createReadStream(files.photo.path);
ous = fs.createWriteStream(__dirname + '/directory were u want to store image/' + files.photo.filename);
util.pump(ins, ous, function(err) {
if(err) {
next(err);
} else {
res.redirect('/photos');
}
});
//console.log('\nUploaded %s to %s', files.photo.filename, files.photo.path);
//res.send('Uploaded ' + files.photo.filename + ' to ' + files.photo.path);
}
});
});
if (!module.parent) {
app.listen(8000);
console.log("Express server listening on port %d, log on to http://127.0.0.1:8000", app.address().port);
}
You can also use the following to set a path where it saves the file.
req.form.uploadDir = "<path>";
I created an example that uses Express and Multer. It is very simple and avoids all Connect warnings
It might help somebody.
Again if you don't want to use bodyParser, the following works:
var express = require('express');
var http = require('http');
var app = express();
app.use(express.static('./public'));
app.configure(function(){
app.use(express.methodOverride());
app.use(express.multipart({
uploadDir: './uploads',
keepExtensions: true
}));
});
app.use(app.router);
app.get('/upload', function(req, res){
// Render page with upload form
res.render('upload');
});
app.post('/upload', function(req, res){
// Returns json of uploaded file
res.json(req.files);
});
http.createServer(app).listen(3000, function() {
console.log('App started');
});
For Express 3.0, if you want to use the formidable events, you must remove the multipart middleware, so you can create the new instance of it.
To do this:
app.use(express.bodyParser());
Can be written as:
app.use(express.json());
app.use(express.urlencoded());
app.use(express.multipart()); // Remove this line
And now create the form object:
exports.upload = function(req, res) {
var form = new formidable.IncomingForm;
form.keepExtensions = true;
form.uploadDir = 'tmp/';
form.parse(req, function(err, fields, files){
if (err) return res.end('You found error');
// Do something with files.image etc
console.log(files.image);
});
form.on('progress', function(bytesReceived, bytesExpected) {
console.log(bytesReceived + ' ' + bytesExpected);
});
form.on('error', function(err) {
res.writeHead(400, {'content-type': 'text/plain'}); // 400: Bad Request
res.end('error:\n\n'+util.inspect(err));
});
res.end('Done');
return;
};
I have also posted this on my blog, Getting formidable form object in Express 3.0 on upload.
I know that the original question related to specific versions, but it also referred to the "latest" - #JohnAllen 's post is no longer relevant due to Expressjs bodyParser and connect-form
This demonstrates the easy to use in-built bodyParser():
/**
* Module dependencies.
*/
var express = require('express')
var app = express()
app.use(express.bodyParser({ keepExtensions: true, uploadDir: '/home/svn/rest-api/uploaded' }))
app.get('/', function(req, res){
res.send('<form method="post" enctype="multipart/form-data">'
+ '<p>Image: <input type="file" name="image" /></p>'
+ '<p><input type="submit" value="Upload" /></p>'
+ '</form>');
});
app.post('/', function(req, res, next){
res.send('Uploaded: ' + req.files.image.name)
return next()
});
app.listen(3000);
console.log('Express app started on port 3000');
There's my method to multiple upload file:
Nodejs :
router.post('/upload', function(req , res) {
var multiparty = require('multiparty');
var form = new multiparty.Form();
var fs = require('fs');
form.parse(req, function(err, fields, files) {
var imgArray = files.imatges;
for (var i = 0; i < imgArray.length; i++) {
var newPath = './public/uploads/'+fields.imgName+'/';
var singleImg = imgArray[i];
newPath+= singleImg.originalFilename;
readAndWriteFile(singleImg, newPath);
}
res.send("File uploaded to: " + newPath);
});
function readAndWriteFile(singleImg, newPath) {
fs.readFile(singleImg.path , function(err,data) {
fs.writeFile(newPath,data, function(err) {
if (err) console.log('ERRRRRR!! :'+err);
console.log('Fitxer: '+singleImg.originalFilename +' - '+ newPath);
})
})
}
})
Make sure your form has enctype="multipart/form-data"
I hope this gives you a hand ;)
Here's a way to upload your images using the formidable package, which is recommended over bodyParser in later versions of Express. This also includes the ability to resize your images on the fly:
From my website: Uploading and Resizing Images (on the fly) With Node.js and Express.
Here's the gist:
var express = require("express"),
app = express(),
formidable = require('formidable'),
util = require('util')
fs = require('fs-extra'),
qt = require('quickthumb');
// Use quickthumb
app.use(qt.static(__dirname + '/'));
app.post('/upload', function (req, res){
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
res.writeHead(200, {'content-type': 'text/plain'});
res.write('received upload:\n\n');
res.end(util.inspect({fields: fields, files: files}));
});
form.on('end', function(fields, files) {
/* Temporary location of our uploaded file */
var temp_path = this.openedFiles[0].path;
/* The file name of the uploaded file */
var file_name = this.openedFiles[0].name;
/* Location where we want to copy the uploaded file */
var new_location = 'uploads/';
fs.copy(temp_path, new_location + file_name, function(err) {
if (err) {
console.error(err);
} else {
console.log("success!")
}
});
});
});
// Show the upload form
app.get('/', function (req, res){
res.writeHead(200, {'Content-Type': 'text/html' });
/* Display the file upload form. */
form = '<form action="/upload" enctype="multipart/form-data" method="post">'+ '<input name="title" type="text" />
'+ '<input multiple="multiple" name="upload" type="file" />
'+ '<input type="submit" value="Upload" />'+ '</form>';
res.end(form);
});
app.listen(8080);
NOTE: This requires Image Magick for the quick thumb resizing.
It will become easy to store files after converting in string you just have to convert string in image in your frontend
convert image in to base64 string using this code in your api and also don't forgot to delete file from upload folder
"img": new Buffer.from(fs.readFileSync(req.file.path)).toString("base64")
to delete the file
let resultHandler = function (err) {
if (err) {
console.log("unlink failed", err);
} else {
console.log("file deleted");
}
}
fs.unlink(req.file.path, resultHandler);
at your routes import multer
`multer const multer = require('multer');
const upload = multer({ dest: __dirname + '/uploads/images' });`
Add upload.single('img') in your request
router.post('/fellows-details', authorize([Role.ADMIN, Role.USER]),
upload.single('img'), usersController.fellowsdetails);
OR
If you want save images in localstorage and want save path in database you can try following approach
you have to install first the fs-extra which will create folder. I am creating separate folders by id's if you want to remove it you can remove it. and
to save path of image where it is uploaded add this code in your api or controller you are using to save image and and add it in database with other data
let Id = req.body.id;
let path = `tmp/daily_gasoline_report/${Id}`;
create separate folder for multer like multerHelper.js
const multer = require('multer');
let fs = require('fs-extra');
let storage = multer.diskStorage({
destination: function (req, file, cb) {
let Id = req.body.id;
let path = `tmp/daily_gasoline_report/${Id}`;
fs.mkdirsSync(path);
cb(null, path);
},
filename: function (req, file, cb) {
// console.log(file);
let extArray = file.mimetype.split("/");
let extension = extArray[extArray.length - 1];
cb(null, file.fieldname + '-' + Date.now() + "." + extension);
}
})
let upload = multer({ storage: storage });
let createUserImage = upload.array('images', 100);
let multerHelper = {
createUserImage,
}
module.exports = multerHelper;
In your routes import multerhelper file
const multerHelper = require("../helpers/multer_helper");
router.post(multerHelper. createUserImage , function(req, res, next) {
//Here accessing the body datas.
})

Resources