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
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 ?
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 })
});
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.
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
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
});