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>
CodePudding user response:
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 
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 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"



