Upload an image and save it as base64 - node.js

First in nodejs, I have succeeded to upload an image (using multer) through postman. Now I am trying to save it not as a png/jpg file, but as a base64 encrypted text file on disk. Any suggestions ?
const express=require('express');
const mongoose= require('mongoose');
const bodyparser=require('body-parser');
const cookieParser=require('cookie-parser');
const db=require('./config/config').get(process.env.NODE_ENV);
const multer = require("multer");
const path = require('path');
var fs = require('fs');
const imageStorage = multer.diskStorage({
// Destination to store image
destination: 'images',
filename: (req, file, cb) => {
cb(null, file.fieldname + '_' + Date.now()
+ path.extname(file.originalname))
// file.fieldname is name of the field (image)
// path.extname get the uploaded file extension
}
});
const imageUpload = multer({
storage: imageStorage,
limits: {
fileSize: 1000000 // 1000000 Bytes = 1 MB
},
fileFilter(req, file, cb) {
if (!file.originalname.match(/\.(png|jpg)$/)) {
// upload only png and jpg format
return cb(new Error('Please upload a Image'))
}
cb(undefined, true)
}
})
app.post('/api/uploadPicture', imageUpload.single('picture'), (req, res) => {
const contents = fs.readFileSync(req.file.path, {encoding: 'base64'});
let buff = Buffer.from(contents).toString('base64');
console.log(buff);
res.send(req.file);
}, (error, req, res, next) => {
res.status(400).send({ error: error.message })
})
Thanks ahead !

I've some ready snippets which worked well for me before. But I've commented there the part where you save a file with exact image extension. Instead I've saved the file with "txt" extension as you want (in userController).
routes/main.js
router.post('/image/base64', multerUpload.single('image'), userController.uploadBase64Image);
utils/multer.js
const multer = require('multer');
const path = require('path');
module.exports = multer({
storage: multer.diskStorage({
destination: function (req, file, cb) {
const filePath = path.join(__dirname, './../uploads');
cb(null, filePath);
},
filename: function (req, file, cb) {
const extension = file.mimetype.split('/')[1];
const fileName = (new Date().getTime() / 1000 | 0) + '.' + extension;
cb(null, fileName);
}
}),
limits: {
fileSize: 1024 * 1024 * 2 // MB
},
fileFilter: (req, file, cb) => {
let valid = (file.mimetype === 'image/jpeg' || file.mimetype === 'image/jpg' || file.mimetype === 'image/png');
cb(null, valid);
},
});
controllers/user.js
const fs = require('fs');
const path = require('path');
const port = process.env.APP_PORT; // 3000
const appUrl = process.env.APP_URL; // http://127.0.0.1
const uploadBase64Image = async (req, res, next) => {
try {
const encoded = req.body.image;
const base64ToArray = encoded.split(";base64,");
// const prefix = base64ToArray[0];
// const extension = prefix.replace(/^data:image\//, '');
const extension = 'txt';
// if (extension === 'jpeg' || extension === 'jpg' || extension === 'png')
// {
const imageData = base64ToArray[1];
const fileName = (new Date().getTime() / 1000|0) + '.' + extension;
const imagePath = path.join(__dirname, './../uploads/') + fileName;
fs.writeFileSync(imagePath, imageData, { encoding: 'base64' });
return res.status(201).json({
error: false,
message: "Base64 Image was successfully uploaded.",
url: `${appUrl}:${port}/images/${fileName}`
});
// }
// else {
// return res.status(403).json({
// error: true,
// message: "Base64 data not valid!",
// });
// }
}
catch (e) {
return res.status(403).json({
error: true,
message: e.message,
});
}
}

Related

req.file is undefined when uploading an image through Postman

I am trying to write a code that is uploading an image (jpg / png), and the req.file in the code is undefined. I have tried to change it to req.files, and same thing.
const express=require('express');
const mongoose= require('mongoose');
const bodyparser=require('body-parser');
const cookieParser=require('cookie-parser');
const multer = require("multer");
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/uploads')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
const fileFilter = (req, file, cb)=>{
if(file.mimetype === 'image/jpg' || file.mimetype === 'image/png'){
cb(null,true);
}else{
cb(null,false);
}
}
const upload = multer({
storage:storage,
fileFilter:fileFilter
});
app.post('/api/uploadPicture', upload.single('picture'), (req, res) => {
console.log(req.files);
if(req.file) {
const pathName = req.file.path;
res.send(req.file,pathName);
}
else throw 'error';
});
Any ideas? Why is that happening ?

Uploading file using multer triggers process.on('SIGINT')

When I upload file using multer nodemon restarts web server. It's fine on my local machine which is windows. It only happens when I start my server on ubuntu machine. What's the problem? My code is here below.
const path = require("path");
const multer = require("multer");
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, path.join(__dirname, '../public/uploads/'))
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
});
function checkFileType(file, cb) {
const filetypes = /jpeg|jpg|png|gif/;
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
const mimetype = filetypes.test(file.mimetype);
if (mimetype && extname) {
return cb(null, true);
} else {
cb('Only images! jpeg|jpg|png|gif ');
}
}
const upload = multer({
storage: storage,
limits: { fileSize: 5242880 },
fileFilter: function (_req, file, cb) {
checkFileType(file, cb);
}
});
router.route('/upload').post(protect, upload.array('banner', 12), (req, res, next) => {
console.log(req.files)
if (!req.files) {
res.status(400).json({ success: false, message: 'File not found' });
return;
}
const data = [];
const baseUrl = `THE_URL_FILE_UPLOAD`;
req.files.map((file, idx) => {
data.push({ path: baseUrl + file.originalname })
})
res.status(200).json({ success: true, data })
});

how can I upload file in Node JS?

I have problem while trying to upload file.
I use mongo as database and reactjs for frontend.
file appears in the database but it does not appear in the project.
I wanna appear in the directory which I set in the code.
And this is backend API.
const express = require("express");
const fileRoutes = express.Router();
let File = require("../../models/File");
const multer = require("multer");
const fs = require("fs-extra");
const storageBase = require("../../config/keys").storageBase;
const isEmpty = require("is-empty");
const addDays = require("date-fns").addDays;
const moment = require("moment-timezone");
// const fileUpload = require("express-fileupload");
// app.use(fileUpload());
var storage = multer.diskStorage({
destination: function (req, file, cb) {
const { file_type, file_owner } = req.query;
const path =
`${storageBase}` +
`${file_type}/${moment(new Date()).tz("Asia/Shanghai").format("YYYY-MM/MM-DD")}/${file_owner}`;
if (!fs.existsSync(path)) {
fs.mkdirsSync(path);
}
cb(null, path);
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
});
var upload = multer({
storage: storage,
limits:{
files: 5,
fieldSize: 4096 * 1024 * 1024
}
});
fileRoutes
.route("/upload")
.post(upload.single("file_data"), function (req, res) {
const {
file_type,
file_description1,
file_description2,
file_description3,
file_owner,
file_owner_job,
file_register_date,
hour,
minute
} = req.query;
let file = new File({
file_type: file_type,
file_url: req.query.file_register_date + "/" + req.files.file_data.name,
file_description1: file_description1,
file_description2: file_description2,
file_description3: file_description3,
file_owner: file_owner,
file_owner_job: file_owner_job,
file_register_date: file_register_date + " " + hour + ":" + minute
});
file
.save()
.then(file => {
res.status(200).json({ file: "file uploaded successfully" });
})
.catch(err => {
res.status(400).send("upload failed");
});
});
module.exports = fileRoutes;
But file which I select for upload does not save in my project
If u know how to do pls help me.

Issue with multer and router.post(). cannot read property 'any'

I have a multer issue when I am trying to use it my .post path.
My route looks like this:
const fileUpload = require('../middleware/fileUpload');
router.post(
'/projects/create/:userId',
authCheck,
isAdmin,
addProjectToUser,
fileUpload.any(),
create
);
And my file upload is:
const multer = require('multer');
const { v1: uuidv1 } = require('uuid');
const MIME_TYPE_MAP = {
'image/png': 'png',
'image/jpg': 'jpg',
'image/jpeg': 'jpeg',
};
const fileUpload = multer({
limits: 500000,
storage: multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/images');
},
filename: (req, file, cb) => {
const ext = MIME_TYPE_MAP[file.mimetype];
cb(null, uuidv1() + '.' + ext);
},
}),
fileFilter: (req, file, cb) => {
const isValid = !!MIME_TYPE_MAP[file.mimetype];
let err = isValid ? null : new Error('Invalid Mime Type!');
cb(err, isValid);
},
});
module.export = fileUpload;
I do get const photUpload = fileUpload.any(); TypeError: Cannot read property 'any' of undefined
Not sure wht is worng with this. Any suggestions?
module.exports = fileUpload;
Notice the extra s in exports

Multer fileFilter is not getting called and req.body is empty

for some reason the fileFilter on multer is not getting called.
here is my Controller (i am using express routers)
const express = require('express');
const router = express.Router();
const UploadController = require('../controllers/UploadController');
router.route('/upload').post(UploadController.upload);
module.exports = router;
and this is the controller
const multer = require('multer');
const fs = require('fs');
module.exports = {
upload: function (req, res) {
let storage = multer.diskStorage({
destination: function (req, file, cb) {
console.log('here');
const filesDir = './uploads/' + req.body.ref;
if (!fs.existsSync(filesDir)) {
fs.mkdirSync(filesDir);
}
cb(null, filesDir);
},
filename: function (req, file, cb) {
let extArray = file.mimetype.split("/");
let extension = extArray[extArray.length - 1];
cb(null, req.body.type + '-' + Date.now() + '.' + extension);
},
fileFilter : function (req, file, cb) {
if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) {
return cb(new Error('Only image files are allowed!'), false);
}
cb(null, true);
}
})
const upload = multer({ storage: storage }).single('file');
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
res.send({
error: err
});
} else if (err) {
res.send({
error: err
});
}else{
res.send({
file: req.file,
body: req.body
});
}
});
}
}
I have following issues:
The fileFilter function is not even called so its not validating files
the req.body on the upload function (upload: function (req, res)) is empty it is only available in diskStorage and last upload function (upload(req, res, function (err)) so i cannot validate the body data also.
I had the same problem. the fileFilter function has to be defined inside multer, not inside the diskStorage function.
To make it a bit more readable I defined the storage and filter in variables instead of making everything inside the multer call.
// storage settings
const multerStorage = multer.diskStorage({
destination: function(req, file, next) {
next(null, './public/files');
},
filename: function(req, file, next) {
const sanitizedName = file.originalname
.replace('/[^a-z0-9\./gi', '-')
.replace('/-{2,}/g', '-')
.toLowerCase();
const name = Date.now() + '-' + sanitizedName;
// sending the file name to be stored in the database
req.body.filename = name;
next(null, name);
},
limits: {
fileSize: 25000000
}
});
// filter function
const multerFilter = function(req, file, cb) {
const ext = path.extname(file.originalname).toLowerCase();
if (ext !== '.pdf') {
cb(new Error('File must be in PDF format.'));
}
cb(null, true);
}
And then applying the storage settings and filter function to multer:
const upload = multer({
storage: multerStorage,
fileFilter: multerFilter
});

Resources