I'm using multer as express middleware to upload a file like so:
const upload = multer().single('fieldName');
router.post(
'/',
upload,
(req, res) => {
console.log(req.file)
}
);
It works fine except when I sent the form without a file. Then apparently the upload middleware is just skipped and req.file is undefined.
I tried to add a filter like so but apparently the filter function is not called when there is no file:
function fileFilter(req, file, cb) {
console.log('filtering'); //never reached when file is missing
if (!file) {
return cb(new Error('no file', false));
}
cb(null, true);
}
const upload = multer({fileFilter: fileFilter}).single('fieldName');
router.post(...)
Is there any way to handle the missing file inside the multer middleware? Or do I have to check afterwards?
check in you html form "fieldName" in input name
and this can you help
in you routes app
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now()+'.mp3')
}
})
var upload = multer({ storage: storage })
router.post(
'/uploadfile',upload.single('fieldName'),
)
Related
I'm new in using nodejs and multer and I want to upload an image but in two different directories. I tried using two different middleware but since the first multer function returns a file destination I couldnt use it to upload in the other multer function. Is it possbile to upload a file using multer in two different directories?
Create multiple storages and call them at the same time.
Example:
const app = require("express")();
const multer = require('multer');
const storageA = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './storageA/');
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
});
const storageB = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './storageB/');
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
});
const destA = multer({ storage: storageA });
const destB = multer({ storage: storageB });
function fileUpload(req, res, next) {
destA.single('file')(req, res, next);
destB.single('file')(req, res, next);
}
app.post("/", fileUpload, (req, res) => {
res.json({ file: req.file });
});
app.listen(3000, () => {
console.log("Server started");
});
The uploaded file will be store in ./storageA and ./storageB.
This is not an official way, but went I try it, it works!
Iam using busboy body parser to parse the multipart form data. So Iam getting the fields like name, username key values in req.body and files in req.files. But Iam unable to upload files to the directory using multer.
app.use(busboyBodyParser());
app.post('/createUser', (req, res) => {
console.log(req.body);
console.log(req.files);
const storage = multer.diskStorage({
destination: './public/uploads/',
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() +
path.extname(file.originalname));
}
});
const upload = multer({
storage: storage
}).single(req.files['uploadpic']);
upload(req, res, (err) => {
});
});
You don't need to use busboy with multer as it is built on top of it.
Your files are not being saved because your files come in an array form but you're trying to read it in as a single file also with a wrong syntax.
upload.single('fieldName') //is the syntax for single file
Your code will be rewritten like this:
//removing busbodyparser
//declaring multer configs
const storage = multer.diskStorage({
destination: './public/uploads/',
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() +
path.extname(file.originalname));
}
});
const upload = multer({
storage: storage
}).array('uploadpic', 8]
//make sure you define maxCount - here 8 is given as an example
//array will take in a number of files with the same 'uploadpic' field name
app.post('/createUser', (req, res) => {
upload(req, res, function(err) {
if (err) {
//show error
}
//your files are saved and req.body and req.files are populated using multer
console.log(req.files);
console.log(req.body);
});
});
I am trying to upload an image using express but I am facing two problems, first, whenever I upload the same image again it's not getting uploaded and secondly after uploading any single image a file with image also uploading. Here is my code.
var multer = require('multer');
var uploads = multer({dest: './images'});
app.post('/uploading', uploads.single("file"), function (req, res) {
var file = __dirname +"/images" + "/" + req.file.originalname;
fs.readFile( req.file.path, function (err, data) {
fs.writeFile(file, data, function (err,data) {
if( err ){
console.error( err );
response = {
message: 'Sorry, file couldn\'t be uploaded.',
filename: req.file.originalname
};
}else{
response = {
message: 'File uploaded successfully',
filename: req.file.originalname
};
}
res.end( JSON.stringify( response ) );
});
});
})
The uploads.single("file") middleware Will handle the file upload. You don't have to specifically fs.read and fs.write the file.
var multer = require('multer');
var uploads = multer({dest: './images'});
app.post('/uploading', uploads.single("file"), function (req, res) {
//the file is uploaded automatically
})
EDIT: The above code will upload the file with hex string as filename without any extension.
In order to add rename function you need to use diskStorage. Here is the code taken from this github issue page.
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './images/')
},
filename: function (req, file, cb) {
crypto.pseudoRandomBytes(16, function (err, raw) {
cb(null, raw.toString('hex') + Date.now() + '.' + mime.extension(file.mimetype)); //this is the rename func
});
}
});
var uploads = multer({ storage: storage });
app.post('/uploading', uploads.single("file"), function (req, res) {
//the file is uploaded automatically
})
Now you can use the uploads variable as middleware as shown in the above snippet.
you can edit the filename: function (req, file, cb) { .. } according to your needs. Now the filename will be, <16characterhexstring>.ext
another way to handle it will be not using middleware and using multer manually with below options :
try {
var storage = multer.diskStorage({
destination: function(request, file, callback) {
//define folder here by fs.mkdirSync(anyDirName);
},
filename: function(req, file, callback) {
callback(null, anyFileName);
},
limits: self.limits
});
var upload = multer({
storage: storage,
fileFilter: function(request, file, callback) {
// here you can filter out what not to upload..
}
}).any();
upload(request, response, callback);
} catch (e) {
}
hope this helps!
It simply doesn't save anything to the destination folder i specified.
i tried {storage:storage} instead of {dest: 'storage/'} but it didn't work either.
the image data is actually sent to the server as its console logged. and the dest i specified is created by default but remain empty.
const express = require('express');
const app = express();
const multer = require('multer');
let storage = multer.diskStorage({
destination: '/public/my-uploads',
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
});
const upload = multer({dest:'storage/'}).single('file');
app.post('/upload', upload, (req , res) => {
console.log(req.files) // this does log the uploaded image data.
})
***** EDIT ******
HTML
<form onSubmit={this.upload} enctype='multipart/form-data'>
<input type='file' name='image' />
<input type='submit' value='upload' />
</form>
JS
upload(e){
e.preventDefault();
const file = e.target[0].files[0];
console.log(file)
const fm = new FormData();
fm.append('file', file);
console.log(fm)
axios.post('/upload', fm);
}
POSTMAN
Try to catch the error my calling the middleware yourself:
var upload = multer().single('avatar')
app.post('/upload', function (req, res) {
upload(req, res, function (err) {
if (err) {
// An error occurred when uploading
return
}
// Everything went fine
})
})
Also, change the storage to this:
let storage = multer.diskStorage({
destination: function(req, file, ca) {
cb(null, '/public/my-uploads');
}
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
});
It's been a while, the issue was that I wasn't using the multer middleware at all so the callback code for handling the image was never executed.
I didn't know much about how express worked back then.
Seems you are not using the storage variable and use a function for the destination key, as written in the documentation, also you need to pass your file in the input field named field otherwise multer can't store the file, create an storage folder on the same level as the code :
const http = require('http')
const port = 3000
const express = require('express');
const app = express();
const multer = require('multer');
const server = http.createServer(app)
let storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './storage')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
});
const upload = multer({ storage }).single('file');
app.post('/upload', upload, (req, res) => {
console.log(req.files) // this does log the uploaded image data.
})
// bind the server on port
server.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err)
}
console.log(`server is listening on ${port}`)
})
The name of the "single" in ...single('file') must match the name in the input (containing the file) <input type="file" name='image' /> - and it does not in your example.
Change the multer-part to this ...single('image') - as in the input name='image'
Try this File Storage For Save image in Local
const fileStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "images");
},
filename: (req, file, cb) => {
cb(
null,
new Date().toISOString().replace(/:/g, "-") + "-" + file.originalname
);
},
});
I'm using "multer": "^1.0.6", And i Want to save image in upload folder.
My code is
app.post('/post', multer({dest: './uploads/'}).single('file'), function (req, res) {
response = {
message: 'File uploaded successfully',
filename: req.file.filename
};
res.end(JSON.stringify(response));
});
But I Have the file with this name in upload folder 8e6e425f8756e0bafb40ed1a3cb86964
Why I have this name without mimetype?
Multer saves files without extensions you can read this on GitHub:
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.
If you want to save with the extension that you write your code like here:
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '/tmp/my-uploads')
},
filename: function (req, file, cb) {
cb(null, file.originalname); // modified here or user file.mimetype
}
})
var upload = multer({ storage: storage })
All information you can find here https://github.com/expressjs/multer/blob/master/README.md
Multer not worried about the extension of the file and leave it completely on your side: you have to define itself a function that will do it. For example, like this:
var multer = require('multer');
var upload = multer({ storage: multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads');
},
filename: function (req, file, cb) {
var ext = require('path').extname(file.originalname);
ext = ext.length>1 ? ext : "." + require('mime').extension(file.mimetype);
require('crypto').pseudoRandomBytes(16, function (err, raw) {
cb(null, (err ? undefined : raw.toString('hex') ) + ext);
});
}
})});
app.post('/post', upload.single('file'), function (req, res) {
response = {
message: 'File uploaded successfully',
filename: req.file.filename
};
res.end(JSON.stringify(response));
});