Here is the code which allows to upload files. Which I want to delete If lastClick (defined at download.js) is 1 day.
let storage = multer.diskStorage({
destination: (req, file, cb) => cb(null, 'uploads/'),
filename: (req, file, cb) => {
const uniqueName = `${Date.now()}-${Math.round(Math.random() * 1E9)}${path.extname(file.originalname)}`;
cb(null, uniqueName)
}
});
let upload = multer({
storage: storage,
limits: {
fileSize: 16106119114
},
}).single('file'); //100mb
router.post('/', (req, res) => {
upload(req, res, async (err) => {
if (err) {
return res.status(500).send({
error: err.message
});
}
const file = new File({
guploadBy: req.user.googleId,
fuploadBy: req.user.facebookId,
tuploadBy: req.user.twitterId,
uploaderName: req.user.name,
fileName: req.file.filename,
originalName: req.file.originalname,
provider: req.user.provider,
path: req.file.path,
fileSize: Math.round((req.file.size * (1 / 1000000))),
adultContent: req.body.select,
uuid_s: shortid.generate(),
uuid_d: uuidv4()
});
const response = await file.save();
});
Below I have written code to delete the files after (lastClick + 1 Day) and this should run every 1 min.
setInterval(findRemoveSync.bind(this,__dirname + '/uploads', {age: {seconds: 60}}), req.file.lastClick+86,400,000)
Can anyone tell me whats wrong with my code?
Related
i have no errors and i got req.files in my console but the file is not created in destination directory
i have tried to upload images through multer
this code is admin controllers .js file
const storages = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "./public/product");
console.log(file)
},
filename: (req, file, cb) => {
cb(null, Date.now() + file.originalname);
console.log("gettin the filename")
},
});
const multipleUpload = multer({ storages });
adminAddproduct_post: async (req, res) => {
try {
const product = new Products({
product_id: randomId(len, pattern),
productName: req.body.productName,
productColor: req.body.productColor,
productInStock: req.body.productInStock,
productPrize: req.body.productPrice,
productSize: req.body.productSize,
productImage: req.files.map(file => Date.now() + file.originalname),
});
const result = await product.save((err) => {
if (err) {
console.log("this is the " + err);
} else {
console.log("product save successfully");
}
});
} catch (e) {
console.log(e);
}
res.redirect("/admin/add-product")
},
storages: multipleUpload,
i can console req.files from adminAddProduct
this code in admin.js my route file
const {storages} = adminController
router.post("/add-product" , storages.array("uploads" , 4), adminController.adminAddproduct_post)
Here in your code where you are doing:- productImage: req.files.map(file => Date.now() + file.originalname),
Instead of it you can do:-
let filenames = req.files.map((file) => {
return `${localhost:3000}/uploads/${file.filename}`;
});
below const multipleUpload = multer({ storages });
and you can put productImage: filenames, and save the product.
And you should also check in your model that you made the productImage as array like this productImage: [{ type: String, required: true }],
May this might be helpful to you!
Here is the code how I use to implement multer in my project:-
import multer from "multer";
import path from "path";
import baseUrl from "../../helpers/baseUrl";
const upload = multer({
storage: multer.diskStorage({
destination: "./public/uploads",
filename: (req, file, cb) => {
console.log(req.files);
// console.log("files " + file);
cb(
null,
req.files[0].fieldname + "_" + Date.now() +
path.extname(file.originalname)
);
},
}),
});
// This is the middleware which I am using for my next js project.
apiRoute.use(upload.array("img", 5));
apiRoute.post(async (req, res) => {
const products = await Product.find();
console.log(req.files);
let filenames = req.files.map((file) =>{
return `${baseUrl}/uploads/${file.filename}`;
})
console.log("filenames: ", filenames);
let p = new Product({
title: req.body.title,
slug: req.body.slug,
desc: req.body.desc,
img: filenames,
category: req.body.category,
size: req.body.size,
color: req.body.color,
price: req.body.price,
availableQty: req.body.availableQty,
});
await p.save();
res.status(200).json({ data: "success", products });
});
I have an express server. When the user goes to make a post request for the profiel. They submit a profile picture. I am trying to use multer to grab that photo/image that is being sent and store it in a folder on the backend directory.
I setup multer but for some reason it is not saving any of the photos that I want it to save locally so that I can retrieve it. How can I fix this issue. Does anyone have an idea on how to go about this.
controller:
const Profile = require("../../models/UserModels/Profiles.js")
const User = require('../../models/UserModels/Users.js')
const multer = require('multer')
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '../../client/images/profile/')
},
filename: function (req, file, cb) {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
cb(null, file.fieldname + '-' + uniqueSuffix)
}
})
const upload = multer({ storage: storage })
...
post:(req, res) => {
console.log(req.body)
console.log(req.files)
upload.single(req.files.profile_pic.name) <----------------
let body = req.body
Profile.create({
profile_pic: req.files.profile_pic.name,
f_name: body.f_name,
l_name: body.l_name,
bio: body.bio,
location: body.location,
sm_facebook: body.sm_facebook,
sm_instagram: body.sm_instagram,
sm_twitter: body.sm_twitter,
sm_website: body.sm_website,
followers: body.followers,
following: body.following,
photos: body.photos,
downloads: body.downloads,
edits: body.edits,
userId: body.userId
})
.then((data) => {
res.send(data).status(200)
})
.catch((err) => {
console.error(err)
res.send(err).status(400)
})
},
Here is the direcory for this backend:
-----------update---------------
this is the react axios request from the frontend:
function createProfile(userId){
let data = new FormData()
data.append('f_name', firstName)
data.append('l_name', lastName)
data.append('bio', bio)
data.append('location', location)
data.append('sm_facebook', facebook)
data.append('sm_instagram', instagram)
data.append('sm_twitter', twitter)
data.append('sm_website', website)
data.append('followers', 0)
data.append('following', 0)
data.append('photos', 0)
data.append('edits', 0)
data.append('downloads', 0)
data.append('userId', userId)
data.append('profile_pic', profilePicture)
console.log(data)
axios({
method: "post",
url: "/api/profile/",
data: data,
headers: { "Content-Type": "multipart/form-data" },
})
.then((data) => {
return(<Navigate to='/' />)
})
.catch((err) => {
console.error(err)
})
}
You have to specify the storage path for multer as if you were located on the root folder of the project.
So instead of using '../../client/images/profile/' as storage path, you should use: './backend/client/images/profile'.
You'll code should end up as follows:
const multer = require('multer')
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './backend/client/images/profile')
},
filename: function (req, file, cb) {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
cb(null, file.fieldname + '-' + uniqueSuffix)
}
})
How do I catch the error invoked and return a res status msg? I am unable to catch any error in userController.uploadFile and if I tried to do a upload(req,res (err) in the routes.post, req is not defined.
var storage = multer.diskStorage({
destination(req, file, cb) {
cb(null, url);
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
}
}).single('file');
let upload = multer({
storage: storage,
limits: { fileSize: maxSize },
fileFilter: (req, file, cb) => {
console.log(file);
if (file.mimetype !== 'image/jpeg' || file.mimetype !== 'image/png') {
return cb(new Error('Only jpeg images allowed'))
}
cb(null, true)
}
});
routes.post('/fileupload', upload, userController.uploadFile);
I think we can get this to work with a little tweaking. I've made these changes and tested with a few images.
Your user controller will look a little different, but something like this should work.
I've updated to pass any file too large error to the controller, again this will be in the req.uploadError property, so you can handle as you like.
const userController = {
uploadFile(req, res) {
if (req.uploadError) {
res.status(400).send("An error occurred - " + req.uploadError.message);
} else {
res.status(201).send("All good");
}
}
}
var storage = multer.diskStorage({
destination(req, file, cb) {
cb(null, url);
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
}
});
let upload = multer({
storage: storage,
limits: { fileSize: maxSize },
fileFilter: (req, file, cb) => {
console.log(file);
if (file.mimetype !== 'image/jpeg' && file.mimetype !== 'image/png') {
cb(new Error('Only jpeg or png images allowed'));
} else {
cb(null, true);
}
}
}).single('file');
routes.post('/fileupload', (req, res, next) => {
upload(req, res, err => {
req.uploadError = err;
next();
})
}, userController.uploadFile);
I am trying to change the name of the image im uploading to the server using multer which gives the file a random name.
I user multer.diskStorage method to do so as described in the documentation but it keeps saving the file with random names
CODE:
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null,'./uploads/')
},
fileName: (req,file,cb) => {
cb(null, file.originalname)
}
})
const upload = multer({storage: storage})
router.post('/', upload.single('carImage') ,(req, res) => {
res.send(req.file);
}
RESPONSE :
{
fieldname: 'carImage',
originalname: 'testOCR8.jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: './uploads/',
filename: '229f70c20e5550dbe638db49791ef17d',
path: 'uploads/229f70c20e5550dbe638db49791ef17d',
size: 1712380
}
im uploading to the server using multer which gives the file a random name
You made a typo. It is filename not fileName. This is the standard behavior as per the docs.
filename is used to determine what the file should be named inside the folder. If no filename is given, each file will be given a random name that doesn't include any file extension.
So, your code should be
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null,'./uploads/')
},
filename: (req,file,cb) => { // notice the change 'filename'
cb(null, file.originalname)
}
});
const upload = multer({storage: storage});
Try a different approach for using StorageMulter. Try the following -
var StorageMulter = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, "./temp");
},
filename: function(req, file, callback) {
var uploadFileName = "x.jpg"; //Manipulate this variable accordingly
callback(null, uploadFileName);
}
});
var upload = multer({
storage: StorageMulter
});
app.post("/api/uploaddocument", function(req, res) {
upload(req, res, function(err) {
if (err) {
return res.end("Something went wrong!"+ err);
}
});
});
Currently, I am using multer library to save files on File system. This application is using Node and Express.
I can save the file first on server and then encrypt it. Later on delete the unencrypted file. However, I do not want to add unencrypted file on server directly. So, I am looking for a way to encrypt the incoming file from the front end and then save it to disk.
const defaultFolder = 'upload';
const filePath = resolveHome(process.env.FILE_STORAGE_LOCATION || defaultFolder);
const key = 'test';
const cipher = crypto.createCipher('aes-256-cbc', key);
const decipher = crypto.createDecipher('aes-256-cbc', key);
const upload = multer({
storage: multer.diskStorage({
destination: filePath,
filename: (req, file, cb) => {
const parts = file.originalname.split('.');
const ext = parts.pop();
const name = parts.join('.');
cb(null, name + '-' + Date.now() + '.' + ext);
},
}),
}).single('file');
app.post('/upload', (req, res) => {
upload(req, res, err => {
if (err) {
return res.status(400).send({
error: 'The request was invalid',
fileName: req.file.originalname,
});
}
return res.status(200).send({
fileName: req.file.filename,
});
});
});
I tried to use crypto library to encrypt the file but it's not working. I believe the req.cipher is invalid as I would normally use req.file to get reference to the file.
app.post('/upload', (req, res) => {
upload(req, res, err => {
output = fs.createWriteStream(filePath + '/' + req.file.originalname);
req.pipe(cipher).pipe(output).on('finish', () => console.log('Encrypted file written on disk'));
if (err) {
return res.status(400).send({
error: 'The request was invalid',
fileName: req.file.originalname,
});
}
return res.status(200).send({
fileName: req.file.originalname,
});
});
});
I had tried to just write file without using cipher and file was empty. Adding this information in case it helps.
req.pipe(output).on('finish', () => console.log('Encrypted file written on disk'));
Can you try this
app.post('/upload', function(req, res) {
upload(req, res, function(err) {
var fileName = req.file.destination +"\\"+ req.file.filename
var input = fs.createReadStream(fileName);
var output = fs.createWriteStream(fileName + ".enc");
input.pipe(cipher).pipe(output);
output.on('finish', function() {
fs.unlink(fileName, (err) => {
if (err) throw err;
console.log('Encrypted file written to disk!');
res.end('Encrypted file written to disk!')
});
});
})
})