I am making API for multiple image uploading in node js.
So can you please help me out, how to upload only images and not another file
var Express = require('express');
var multer = require('multer');
var bodyParser = require('body-parser');
var app = Express();
app.use(bodyParser.json());
var Storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, "./Images");
},
filename: function (req, file, callback) {
callback(null, file.fieldname + "_" + Date.now() + "_" + file.originalname);
}
});
var upload = multer({ storage: Storage }).array("imgUploader", 3); //Field name and max count
app.get("/", function (req, res) {
res.sendFile(__dirname + "/index.html");
});
app.post("/api/Upload", function (req, res) {
upload(req, res, function (err) {
if (err) {
return res.end("Something went wrong!");
}
return res.end("File uploaded sucessfully!.");
});
});
You can add a fileFilter function to your multer options. So with a bit of refactoring:
var options = {
storage: multer.diskStorage({
destination: function (req, file, callback) {
callback(null, "./Images");
},
filename: function (req, file, callback) {
callback(null, file.fieldname + "_" + Date.now() + "_" + file.originalname);
}
}),
fileFilter: function (req, file, callback) {
const isPhoto = file.mimetype.indexOf("image/") === 0
if (isPhoto) {
callback(null, true) // true if valid
} else {
callback({ message: 'An optional error message'}, false) // false if invalid
}
}
}
And then use these options:
var upload = multer(options).array("imgUploader", 3);
See: https://github.com/expressjs/multer#filefilter
accept="image/*" on your input will only provide client side validation, and can be removed with the dev console.
Use accept attribute for your input.
<input type="file" name="pic" accept="image/*">
Related
I am trying to upload different types of files to server using multer in an express application. But every time server responds by stating TypeError: req.files is not iterable . I checked and req.files is empty.
Here is the code for the same:
var express = require('express');
var app = express();
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/')
},
filename: function (req, file, cb) {
cb(null, Date.now() + '-' + file.originalname)
}
})
var upload = multer({ storage: storage }).array('userfiles', 10);
app.post('/upload', function (req, res) {
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
// A Multer error occurred when uploading.
return res.status(500).json(err);
} else if (err) {
// An unknown error occurred when uploading.
return res.status(500).json(err);
}
let uploadedFiles = [];
for (let item of req.files) {
uploadedFiles.push({ filename: item.originalname });
}
// Everything went fine.
res.json({ progress: 100, files: uploadedFiles });
})
});
app.listen(8000, (err) => {
if (err) {
console.log('ERROR:', err);
} else {
console.log('working on http://localhost:8000');
}
})
And this is how I am calling this API from postman:
Postman UI
I am unable to figure out where the problem is. Please help me with this.
I ran his code and he tried to store the images at the root of my filesystem.
to refer a a path relative to your current directory you need to use ./
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/') // change 'upload/' to './uṕload'
},
filename: function (req, file, cb) {
cb(null, Date.now() + '-' + file.originalname)
}
})
After this, the code worked.
I am a js-newbie and I am currently trying to use multer to upload some files.
Here is my code:
let express = require('express');
let im = require('imagemagick');
let gm = require("gm").subClass({
imageMagick: true
});
let multer = require('multer');
let app = express();
let storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '/uploads')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
});
var upload = multer({storage: storage}).single('avatar');
app.post('/', function (req, res) {
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
res.json({
success: false,
message: 'error during uploading'
});
} else if (err) {
res.json({
success: false,
message: 'error during uploading'
});
}
res.json({
success: true,
message: 'Image uploaded'
});
})
})
app.listen(3000);
When I send a post-req with a file (form-data), then I get a success message, however the folder with the file is not created:
post request
EDIT:
I managed to upload the file... I had to change the path of the uploads directory in the code like this:
let storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads/')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
});
However the uploads directory hast to be created manually, it is not being created automatically if it is missing...how do I solve this problem?
You can check this issue out:
https://github.com/expressjs/multer/issues/287
It says you should create a directory in 'destination' or as pre-requirements.
I want to upload images using multer. But it is not working. What is wrong here?
This code is in my route file.
var multer = require('multer');
var upload = multer({ dest: 'public/uploads/' });
And this is my post route.
router.post('/addNewFood', upload.single('avatar'),function (req, res, next) {
console.log(req.files);
});
Try this, it works for me. Used express and node.
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/uploads/')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
});
var upload = multer({ storage: storage }).single('avatar');
router.post('/addNewFood', //Your authentication check,//
function (req, res, next) {
upload(req, res, function(err) {
if (err) {
res.redirect(req.headers.referer + "/error.html");
return;
}
if (!req.files) {
res.redirect(req.headers.referer + "/error.html");
return;
} else {
//Implement your own logic if needed. Like moving the file, renaming the file, etc.
res.redirect(req.headers.referer);
}
});
}
);
Make sure you install the package
npm install --save multer
You can try the following way,
In the server side, In your routes or controller file configure the multer:
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/images/uploads')
},
filename: function (req, file, cb) {
cb(null, Date.now() + '-' + file.originalname)
}
})
var upload = multer({ storage: storage });
In the storage object,
destination is stand for, where the file will be uploaded. So make sure in your project directory, /public/images/uploads path is created. Otherwise you may want to change the file path.
Also in storage object filename is stands for, what will be the uploaded file name. Here I add the current time with the original file name to make the all file name unique.
Now in your desired routing, suppose
router.post('/', upload.single('image'), (req, res) => {
//here your other task.
});
Now your file is uploaded. Make sure the client side is using the same name, In this case 'image'.
<input type="file" name="image" id="image" class='form-control'>
This is a single file upload procedure.
For multiple files
router.post('/', upload.array(), function (req, res, next) {
//your task goes here
});
For more information, check this link.
const multer = require("multer");
function fileFilter(req, file, cb) {
if (file.mimetype === "image/jpeg" || file.mimetype === "image/jpg" || file.mimetype === "image/png") {
cb(null, true)
} else {
cb(null, false)
}
cb(new Error('I don\'t have a clue!'))
}
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads')
},
filename: function (req, file, cb) {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
cb(null, file.fieldname + '-' + uniqueSuffix)
}
})
var upload = multer({
storage: storage, limits: {
fieldSize: 1024 * 1024 * 5,
fileFilter: fileFilter
}
})
router.post("/", upload.single("image_url"),(req, res) => {
const new User=new User({
image_url: req.file.path
})
I can not figure out why I get this error.
When I try to run node filename.js, I got a type error on the console:
app.use() requires middleware functions
I expect the result is:
Working on port 3000
Below is my code:
var express = require('express');
var multer = require('multer');
var fs = require('fs');
var app = express();
var DIR = './uploads/';
var upload = multer({dest: DIR});
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://valor-software.github.io');
res.setHeader('Access-Control-Allow-Methods', 'POST');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.use(multer({
dest: DIR,
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);
}
}));
app.get('/api', function (req, res) {
res.end('file catcher example');
});
app.post('/api', function (req, res) {
upload(req, res, function (err) {
if (err) {
return res.end(err.toString());
}
res.end('File is uploaded');
});
});
var PORT = process.env.PORT || 3000;
app.listen(PORT, function () {
console.log('Working on port ' + PORT);
});
According to the document of multer on npm. You can not pass multer object as an argument directly. You should pass them by calling member functions, such as single(), field(), array().
For example:
upload = multer({
dest: DIR,
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);
}
})
app.use(upload.single(...));
app.use(upload.array(...));
app.use(upload.fields(...));
app.use(upload.any());
I am trying to upload images to node.js express
bodyParser need a middleware to handle the image file , or it will reply
token undefine
I use Multer as middle ware , as this said, the req.file should hole a array of information, than I can use req.file.image.path to get the file path and other information, than I can save it as a file.
Here is the problem, I upload an image from Postman, I only write console.log(req.file) it shows undefined.
If I try to write req.file.image.path to get the file path, the error is image undefined, it seems like I didn't use multer well, so the req.file didn't hold the data information, Should I create some temp folder to multer or...?
app.js
var express = require('express')
,bodyParser = require('body-parser')
,app = express()
,multer = require('multer')
,binary = require('binary')
,fs = require('fs')
,util= require('util')
,http = require('http')
,multer = require('multer')
,upload = multer({ dest: '/Node/file-upload/uploads/' });
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies.
app.use(bodyParser.json({limit: '5mb'}));
songs = require('./routes/route');
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
app.post('/upload',songs.upload);
route.js
var mongoose = require('mongoose');
var uri = "mongodb://1111:1111#ds061365.mongolab.com:61365/aweitest";
mongoose.connect(uri);
// we're connected!
var db = mongoose.connection.db;
var BSON = require('bson').BSONPure;
var binary = require('binary');
var body = require('body-parser');
var fs = require('fs');
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, '/Node/file-upload/uploads/');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
}
});
var upload = multer({ storage : storage}).single('image');
db.on('error', console.error.bind(console, 'connection errrrrrrrror:'));
db.once('open', function() {
console.log("mongodb is connected!!");
});
exports.upload = function(req, res) {
upload(req,res,function(err) {
console.log(req.file);
fs.readFile(req.file.image.path, function (err, data){
var dirname = "/Node/file-upload/uploads/";
var newPath = dirname + req.body.filename;
fs.writeFile(newPath, data, function (err) {
if(err) {
return res.end("Error uploading file.");
}
res.end("File is uploaded");
});
});
});
};
error
TypeError: Cannot read property 'image' of undefined
at c:\Users\awei\WebstormProjects\untitled\routes\girlshanlder.js:107:28
You need to set the filename before send the image in the Postman as shown here
Cheers.
Full code for uploading images in your MySQL database and in folder too.
Just define the module and install multer and path and save it.
var multer = require('multer');
var path = require('path');
var storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, './uploadimages')
},
filename: function(req, file, callback) {
callback(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
}
})
app.post('/imginsert',multer({
storage: storage,
fileFilter: function(req, file, callback) {
var ext = path.extname(file.originalname)
if (ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg')
{
return callback(res.end('Only images are allowed'), null)
}
callback(null, true)
}
}).single('img'), function(req, res) {
/*img is the name that you define in the html input type="file" name="img" */
var data = {
table_column_name(your database table column field name) :req.file
};
var query = connection.query("Insert into tablename set ?" ,data,function(err, rows)
{
if (err)
throw err;
res.redirect('/blog');
});
console.log(query.sql);
console.log(req.file);
});