Multer isn't saving to specified destination - node.js

I'm fairly new to nodejs/ express, but no matter what I seem to do I cant seem to get multer to save to the specified destination, it seems to completely ignore the parameter all together. The code is shown below
//app.js
var multer = require('multer');
var fs = require('fs');
var apiRouter = express.Router();
var app = express();
var store = multer.diskStorage({
filename: function(req,file,cb){
console.log("filename");
cb(null, Date.now()+'.'+file.originalname);
},
desitnation: function(req,file,cb){
console.log("storage");
cb(null,'./public/');
}
});
var upload = multer({storage:store}).single('file');
apiRouter.post('/upload', function(req, res){
upload(req, res, function (err) {
if (err) {
return res.end(err.toString());
}
console.log(req.file);
return res.json({originalname:req.file.originalname, uploadname:req.file.filename});
});
});
The response I get when uploading is shown below:
GET /vendor.js.map 200 3.916 ms - 6636755
filename
{ fieldname: 'file',
originalname: 'Desert.jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: 'C:\\Users\\Dwyer\\AppData\\Local\\Temp',
filename: '1538979138829.Desert.jpg',
path:
'C:\\Users\\Dwyer\\AppData\\Local\\Temp\\1538979138829.Desert.jpg',
size: 845941 }
POST /api/upload 200 70.031 ms - 69
It seems to be setting the file correctly, but I'm not sure where it gets the destination from, no3 do I understand why the destination parameter isn't being read.

Its actually "destination" (not desitnation). You should also make sure that you have a folder ,with the specified name, at the specified destination.

Do you try using physical address in destination? I guess destination in multer document is physical address in linux os.

but no matter what I seem to do I cant seem to get multer to save to the specified destination, it seems to completely ignore the parameter all together.
This is because there seem to be a typo in the configuration.
'use strict';
var store = multer.diskStorage({
filename: function (req, file, cb) {
console.log("filename");
cb(null, Date.now() + '.' + file.originalname);
},
destination: function (req, file, cb) { // it is destination not desitnation :)
console.log("storage");
cb(null, './public/');
}
});

Related

Node: multer change destination folder for fields

I have simple multer image uploading.
// Multer settings
// STORAGE FOR USER AVATAR
var storageAvatar = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/uploads/avatars/')
},
filename: function (req, file, cb) {
cb(null, req.user.id + '.jpg')
}
})
// STORAGE FOR ARTICLE THUMBNAILS
var storageThumbnail = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/uploads/thumbnails/')
},
filename: function (req, file, cb) {
cb(null, "clanok" + '.jpg')
}
})
// SETTING UPLOAD FOLDER
var upload = multer({
storage: storageAvatar
})
// Multer BEFORE CSRF!!!
app.use(upload.fields([{
name: 'avatar',
maxCount: 1,
}, {
name: 'thumbnail',
maxCount: 1,
}]));
my problem is that i am unable to set different folder for avatars and thumbnails. I can set only one folder for both :/ Anything else i tried ends with invalid CSRF. Thanks for anny suggestions.
EDIT: in one form i am using only one thing. So for example in profile update i have only possibility to change avatar in article adding i have only ability to change thumbnail of article. They not need to bey in upload fields can be seperate but dont know how.
I found on forum way how to go over csrf problem by adding ?_csrf={{csrfToken}} to the end of action in form so i can use official way of using multer :)

How to upload images to GCS bucket with multer and NodeJS?

I'm facing issues for uploading local images to my google cloud storage.
I've already tried two methods. The first one is uploading with multer
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, './uploads/')
},
filename: (req, file, cb) => {
cb(null, file.fieldname + '-' + Date.now())
}
});
var upload = multer({storage: storage}).single('image');
app.post('/upload',function(req,res,next){
upload(req,res,(err) => {
if(err){
console.log(err)
}else{
console.log(req.file)
}
})
})
Then, i've tried directly with GCS
var bucket = admin.storage().bucket('mybucket')
app.post('/upload',function(req,res,next){
bucket
.save(file)
.then(() => {
})
for both of these solutions , req.files is always undefined whereas req.body is a buffer like this :
<Buffer 2d 2d 2d 2d ...>
when i try to save this buffer on my GCS bucket, i the .jpg/png file is created in my bucket but it is corrupted.
I'm browsing the web seeking for a solution but i found nothing that helped me to overcome this situation.
Any advice ?
You need multer, multer-google-storage and ofcourse bodyParser if you have additional form values. You need to sent data in multipart/form-data
In your .env file
GCS_BUCKET = <bucket name>
GCLOUD_PROJECT = <project id>
GCS_KEYFILE = <key file location>
You can download key file from GCP Console>Your Project>I AM & Admin>Service Accounts
In your route
const multer = require('multer');
const multerGoogleStorage = require("multer-google-storage");
var uploadHandler = multer({
storage: multerGoogleStorage.storageEngine()
});
router.post('/', uploadHandler.single('image'), function (req, res, next) {
const body = req.body;
res.json({fileName: req.file.filename});
res.end();
}
This will store file on to GCS with name [random-string-generated-by-gcs]_[YOUR FILE NAME WITH EXTENTION]. The same can be access under the route via req.file.filename.
Documentation
Make sure you have added enctype="multipart/form-data" attribute to your form. A probable reason for req.files being undefined.

How to view an image in new tab instead of download in NodeJS using Multer

I'm using Multer and express to add image via a form. I have successfully created the file in an uploads folder. When I try to call the url it is being downloaded in a file format. I need to open it in a new tab based on mime type.
What is the best way to achieve this?
Below is my code:
app.use('/images', express.static(__dirname + '/file/uploads/'));
Sample url:
http://localhost:2020/images/b78339184694e2e6864a77d4f3067db5
I added filename in my storage variable to achieve the required result.
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, __dirname+'/file/uploads/')
},
filename: function (req, file, cb) {
console.log(file);
var extArray = file.mimetype.split("/");
var extension = extArray[extArray.length - 1];
var name = crypto.randomBytes(10).toString('hex');
cb(null, name + Date.now()+ '.' +extension)
}
});

Confused with encrypting files and file paths on multer

I'm pretty confused on how to encrypt both files themselves and the file paths using multer. I found this post in regards to encrypting files themselves: How to encrypt file using express multer, but my code wasn't working as it wasn't encrypting the files. I have this:
var fs = require('fs');
var encryptor = require('file-encryptor');
var key = 'My Super Secret Key';
var storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, './uploads/'); // Make sure this folder exists
},
filename: function(req, file, cb) {
var ext = file.originalname.split('.').pop();
cb(null, file.originalname);
}
}),
upload = multer({
onFileUploadComplete: function (file) {
console.log(file.fieldname + ' uploaded to ' + file.path);
// Encrypt file.
encryptor.encryptFile(file, 'encryptedFile.dat', key, function(err) {
// Encryption complete.remove original file
fs.unlink(file);
});
}, storage: storage }).single('uploadedFileField');
2nd Point: I wasn't able to find any resources to find out how to encrypt the file paths as well.
I think you have to put file.path instead of file to encryptor.encryptFile.
I've looked up the source, and encryptor.encryptFile gets string as a first argument.
encryptor.encryptFile(file.path, 'encryptedFile.dat', key, callback);

file upload with multer that contains input name array

i am uploading files with multer nodejs. Everything Works fine but when input type="file" contains name="warranty[][warantycopy]" i am unable to access this file.
Below is my code in index.js:
var multer = require('multer');
var invoice_copies = '';
var storage_Copies = multer.diskStorage({
destination: function (req, file, cb) {
// console.log("fileefefef");
// console.log(file);
cb(null, 'uploads/'+file.fieldname)
},
filename: function (req, file, cb) {
invoice_copies=(file.originalname).replace(/ /g,"_")
cb(null, invoice_copies)
}
});
var uploadCopies = multer({ storage: storage_Copies })
post request contains this code
router.post('/vehicle-battery',uploadCopies.fields([{name:'invoice_copy1'},
{name:'warrantyDetails'}]), function(req, res) {
//my code
}
my jade file is :
form#formAddUser(name="addVehicle",method="post",action="/vehicle-battery",enctype="multipart/form-data")
input(type="file", name="invoice_copy1",class="form-control")
input#warrantyCard(type="text", placeholder="warranty Card Number", name="warrantyDetails[0][warrantyCardNumber]",class="form-control")
input#warrantyCardExpiry(type="text", placeholder="warranty Card Expiry in Month", name="warrantyDetails[0][warrantyCardExpiry]",class="form-control")
input#warrantyCardCopy(type="file", placeholder="warranty Card Expiry copy", name="warrantyDetails[0][warrantyCardCopy]",class="form-control")
textarea(placeholder="Particulars" name="battery_paticulars")
button#btnSubmit(type="submit",class="form-control") submit
if i am using
input#warrantyCardCopy(type="file", placeholder="warranty Card Expiry copy", name="warrantyDetails",class="form-control")
this code working fine.
From a comment above:
after working for research for so long time i solved it . I am providing my solution so that it can help someone else. i have used
router.post('/vehicle-battery',uploadCopies.any(), function(req, res) { //my code }

Resources