I want to filter the files while uploading them to the server but the Multer fileFilter
method is not working.
Backend
destination
and filename
methods are working as well, but fileFilter
is not working.
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "./public/images/");
},
filename: function (req, file, cb) {
cb(null, file.fieldname + path.extname(file.originalname));
},
fileFilter: function (req, file, callback) {
console.log("Hello Word"); // This doesn't work either
var ext = path.extname(file.originalname);
if (!['.jpg', '.jpeg'].includes(ext)) {
return callback(new Error('Only images are allowed'));
}
callback(null, true);
},
});
app.use(
multer({ storage: storage }).fields([
{ name: "logo", maxCount: 1 },
{ name: "favicon", maxCount: 1 },
])
);
Frontend
<form action="" method="post" enctype="multipart/form-data">
<table>
<tbody>
<tr>
<td>Logo</td>
<td>
<input type="file" name="logo" accept="image/jpeg, image/jpg"/>
</td>
</tr>
<tr>
<td>Favicon</td>
<td>
<input type="file" name="favicon" accept="image/x-icon" />
</td>
</tr>
</tbody>
</table>
</form>
Your filterMethod
works fine. This can be checked by changing the value in input accept="image/*"
Then when we try to load a file other than ico
or jpg
we will get an error : Only images are allowed
.
Your code needs some tweaking, additionaly i used the ejs
module, here is my suggestion for a solution:
Folder & File project structure:
app.js - With Your fileFilter
code.
const path = require("path");
const express = require("express");
const multer = require("multer");
const app = express();
app.use(express.static(path.join(__dirname, "public")));
app.set("view engine", "ejs");
app.set("views", path.join(__dirname, "/views"));
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "./images");
},
filename: function (req, file, cb) {
console.log(req.file);
cb(null, new Date().toUTCString() + " - " + file.originalname);
},
});
const upload = multer({
storage: storage,
fileFilter: function (req, file, callback) {
console.log("Hello, World! Works fine;-)");
var ext = path.extname(file.originalname);
if (![".jpg", ".ico"].includes(ext)) {
return callback(new Error("Only images are allowed"));
}
callback(null, true);
},
});
app.post(
"/post",
upload.fields([
{ name: "logo", maxCount: 1 },
{ name: "favicon", maxCount: 1 },
]),
(req, res, next) => {
const files = req.files;
if (!files) {
const error = new Error("Please upload a file");
error.httpStatusCode = 400;
return next(error);
}
res.send(files);
console.log("Success", req.files);
}
);
app.get("/post", (req, res) => {
res.render("post");
});
app.listen(3000, () => {
console.log(`Example app listening at http://localhost:3000/post`);
})
post.ejs - With Your frontend form
code and my additional input submit
:
<form action="" method="post" enctype="multipart/form-data">
<table>
<tbody>
<tr>
<td>Logo</td>
<td>
<input type="file" name="logo" accept="image/jpeg, image/jpg" />
</td>
</tr>
<tr>
<td>Favicon</td>
<td>
<input type="file" name="favicon" accept="image/x-icon" />
</td>
</tr>
</tbody>
</table>
<input class="submit" type="submit" value="Upload File" />
</form>
http://localhost:3000/post
route output in browser:
Output after submit
- Upload File
. Files specified in fields name
logo and favicon.
Output on server side
and in images
folder:
Tested with: node v16.13.0
"ejs": "^3.1.6","express": "^4.17.2","multer": "^1.4.4"