I am using multer to save an image from the client to mongoDB, and then rendering that image to the client as per the requirement.
When attempting to save the image from the frontend, it is getting saved as a .txt document.
How do I save it as a .png? (I am using Express on Node)
var multer = require('multer');
const storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, 'src/');
},
filename: function(req, file, cb) {
cb(null, new Date().toISOString().replace(/:/g, '-')+ file.originalname);
}
});
var upload = multer({ storage: storage });
app.post('/test', upload.single('image'), (req, res, next) => {
var obj = {
name: req.body.name,
desc: req.body.desc,
img: {
data: fs.readFileSync(path.join(__dirname + '/src/' + req.file.filename)),
contentType: 'image/png'
}
}
Image.create(obj, (err, item) => {
if (err) {
console.log(err);
}
else {
item.save();
res.redirect('/admin');
}
});
});
Frontend
<img src="data:image/<%=image.img.contentType%>;base64,
<%=image.img.data.toString('base64')%>">
Upon clicking "Save as"
download.txt
Related
I am developing a MEAN stack app for photo upload and I'm encountering an issue with the follow error. Currently testing this endpoint with postman, everytime I upload an image to the folder the server will stop running and I recieve this error. Any help would be appreciated
node_modules\multer\lib\make-middleware.js:45make-middleware.js:45
next(err)
^
TypeError: next is not a function
In my post.controller.js
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/uploads');
},
filename: function (req, file, cb) {
cb(null, file.originalname + '-' + Date.now() + '-' + getExtension(file));
},
});
const upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 5,
},
});
const getExtension = (file) => {
// this function gets the filename extension by determining mimetype. To be exanded to support others, for example .jpeg or .tiff
var res = '';
if (file.mimetype === 'image/jpeg') res = '.jpg';
if (file.mimetype === 'image/png') res = '.png';
return res;
};
(exports.create = upload.single('imagePath')),
async (req, res, next) => {
try {
console.log(req.file, req.body);
const { title, date } = req.body;
const imagePath = req.file.path;
const post = new Posts({
title,
date,
imagePath,
});
await post.save();
return res.status(200).json({
success: true,
post,
});
} catch (error) {
return res.status(500).json({
success: false,
message: 'Server Error',
error: error,
});
}
};
And my posts.route.js
const express = require('express');
const PostsController = require('../controllers/posts.controller');
const Auth = require('../auth/auth');
const multer = require('multer');
const route = express.Router();
route.post('/create', Auth.authenticateJWT, (req, res) => {
PostsController.create(req, res);
});
route.get('/', Auth.authenticateJWT, (req, res) => {
PostsController.getAllPosts(req, res);
});
route.get('/:id', Auth.authenticateJWT, (req, res) => {
PostsController.getPost(req, res);
});
module.exports = route;
You should define create as:
exports.create = async (req, res, next) => {
try {
console.log(req.file, req.body);
const { title, date } = req.body;
const imagePath = req.file.path;
const post = new Posts({
title,
date,
imagePath,
});
await post.save();
return res.status(200).json({
success: true,
post,
});
} catch (error) {
return res.status(500).json({
success: false,
message: 'Server Error',
error: error,
});
}
};
Export the upload variable:
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/uploads');
},
filename: function (req, file, cb) {
cb(null, file.originalname + '-' + Date.now() + '-' + getExtension(file));
},
});
exports.upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 5,
},
});
And use it as a middleware:
route.post('/create', Auth.authenticateJWT, PostsController.upload('imagePath'), PostsController.create);
I have this router and I'm using multer to store files. I need to varify is 'Key' Exists in the server. Only after that server will store the file.
router.post('/', (req, res) => {
console.log(req.body.key); // empty here
upload(req, res, async (err) => {
if (err) {
console.log(err);
res.send({ error: err.message });
} else {
console.log(req.body.key); //shows the key
store(req.file.filename, {filename: req.file.filename, downloaded: 0, key: req.body.key});
res.send({ success: true, downlink: req.file.filename});
}
});
});
let storage = multer.diskStorage({
destination: (req, file, cb) => cb(null, 'uploads/'),
filename: (req, file, cb) => {
const filename = `${uuid()}-${file.originalname}`;
cb(null, filename);
}
});
let upload = multer({
storage: storage,
limits: { fileSize: 15000000 },
}).single('file'); //name field name
How can I add a checkpoint to prevent Unauthorized file upload?
https://i.stack.imgur.com/gZAHE.png
Here i'm trying to save the image in database using multer but image type is saving as a text format but not in .png , .jpeg, .jpg format,
PLease help me where i'm doing wrong thanks in advance
Schema:-
module.exports = mongoose => {
const Role = mongoose.model(
"role",
mongoose.Schema(
{
roleType : { type:String },
image: { type: String,
data: Buffer}
}
)
);
return Role;
};
controller (Creating an instance):-
exports.addRoleFields = async (req, res) => {
const rolesList = new Role ({
roleType : req.body.roleType,
roleImg : req.file.path,
});
rolesList
.save(rolesList)
.then(data => {
res.status(200).send({ data, statusCode: "200" });
})
.catch(err => {
res.status(500).send({
message: err.message || "Some error occurred while creating.",
statusCode: "500"
});
})
}
}
routes:-
module.exports = app => {
const multer = require("multer"),
storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, 'uploads')
},
filename: function(req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
})
const uploadImg = multer({storage: storage}).single('image');
const roles = require("../controllers/roles.js");
var router = require("express").Router();
router.post("/addRole", uploadImg , roles.addRoleFields);
app.use('/api/roles', router);
};
I simply changed this
filename: function(req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
to
filename: function (req, file, cb) {
cb(null, file.originalname);
}
its working and saving the file
try this for mongodb client
const storage = multer.diskStorage({
destination: async function (req, file, cb) {
let path = 'uploads/' + req.body.path;
if (!fs.existsSync(path)) {
fs.mkdirSync(path, { recursive: true }, (err) => {
if (err) throw err;
});
}
await cb(null, path);
},
filename: function (req, file, cb) {
cb(null, req.body.filename)
}
});
var upload = multer({ storage: storage })
const router = express.Router();
// Upload Image
router.post("/upload", upload.single('image'), (req, res, next) => {
return res.json({
image: req.file.path
});
});
in this upload.single('image'), file should be the name in which formdata carries the file.
in your case,
router.post("/addRole", uploadImg('image'), (req, res)=>{
});
mongoose model
const imgSave = new mongoose.Schema({
img:{
data: Buffer,
contentType: String
}
});
I want to put a profile image into the users collection in mongodb, and I'd like to retrieve this image when user fetch his profile.
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/')
},
filename: (req, file, cb) => {
cb(null, file.fieldname + '-' + Date.now()+ path.extname(file.originalname));
}
});
var upload = multer({ storage: storage });
router.put('/user/profile/img/:email', upload.single('profileimg'), (req, res, next) => {
// console.log(req.file);
Users.findOneAndUpdate({ email: req.params.email }, req.file.filename).then(() => {
Users.findOne({ email: req.params.email }).then((resp, err) => {
res.send(resp);
})
})
})
Image is being saved in upload folder in my api but it's not saved in db.
The second parameter of the findOneAndUpdate function must be an object with the field to update and the value:
Users.findOneAndUpdate({ email: req.params.email }, { profileimg: req.file.filename }).then(...)
You can do it like this code below:
router.put('/user/profile/img/:email', upload.single('profileimg'), async (req, res, next) => {
try {
// check your file is uploaded
// check your field
console.log(req.file);
const result = await Users.findOneAndUpdate({ email: req.params.email }, {$set: { profileimage : req.file.filename}}, { returnOriginal: false})
res.send(result)
} catch(ex) {
res.status(500).send(ex.message);
}
})
Note: For this {$set: { profileimage : req.file.filename}}
profileimage : change with the field in your mongodb
req.file.filename: make sure to console.log(req.file) then, where the field you want to store, use it in here and change this example.
I hope it can help you.
I'm using multer to upload a file. It's uploading fine but I can't work out how to get the generated filename it's made. I'd like to post it back into the response. The filename that's been made is highlighted in the comments:
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '../app/src/assets/game/src/assets/images/')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() + '.png') <!-- I need this in my postback response -->
}
});
const upload = multer({ storage: storage }).single('avatar');
router.post('/upload/', function (req, res) {
upload(req, res, function (err) {
if (err) {
// An error occurred when uploading
throw err;
}
res.json({
sucess: true,
message: 'Image was uploaded successfully'
});
// Everything went fine
})
});
For getting the image name for single image upload use req.file.filename :
res.json({
success: true,
message: 'Image was uploaded successfully',
filename: req.file.filename
});
For getting the images name for multiple images upload use req.files :
let filenames = []
for(let i = 0; i < req.files.length; i++) {
filenames.push(req.files[i].filename);
}
res.json({
success: true,
message: 'Image was uploaded successfully',
filename: filenames
});