I want to upload an array of files, but some elements can be null/undefined. Multer ignores the null files. Is there a way to make Multer maintain the index of non-null files?
E.g. if I upload an array where the first element is null and the second is a file:
------WebKitFormBoundarydFfDIpmAwbAA7GSS
Content-Disposition: form-data; name="photos"
null
------WebKitFormBoundarydFfDIpmAwbAA7GSS
Content-Disposition: form-data; name="photos"; filename="photo.jpg"
Content-Type: image/jpeg
In my request handler, I'd receive an array with 1 element. I wouldn't know if this was the first or second element:
[
{
fieldname: 'photos',
originalname: 'photo.jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: '/tmp',
filename: '24c944fd7975c503c4cc4add4f447aaf',
path: '/tmp/24c944fd7975c503c4cc4add4f447aaf',
size: 837080
}
]
Is there a way to make Multer make the first array element null?
i don't know your code but it should be multer settings
const fileFilter = (req, file, cb) => {
if(file.mimetype === 'image/jpg' || file.mimetype === 'image/jpeg' || file.mimetype === 'image/png'){
cb(null, true)
}else{
cb(new Error('should be png or jpeg'), false)
}
}
const multerStorage = multer.memoryStorage();
const upload = multer({
storage: multerStorage,
fileFilter: fileFilter
});
it should be coming request;
images => request payload data
35 => coming image quantity
router.put('/update', upload.array("images", 35), (req, res)
I hope it helped
Related
I have problem with uploading a images to my FTP server. The problem is that the first array of photos that I'm uploading is uploaded successfully but second time If I'm trying to upload something it isn't working and I don't know why. To uploading files I'm using multer-sftp package.
Code:
const storage = sftpStorage({
sftp: {
host: process.env.FTP_HOST,
user: process.env.FTP_USER,
password: process.env.FTP_PASSWORD,
port: 22,
},
destination: (req: any, file: any, callback: any) => {
callback(null, "");
},
filename: (req: any, file: any, callback: any) => {
callback(null, `${Date.now()}-${file.originalname}`);
},
});
const fileFilter = (
req: Request,
file: Express.Multer.File,
cb: FileFilterCallback
) => {
if (
file.mimetype === "image/png" ||
file.mimetype === "image/jpg" ||
file.mimetype === "image/jpeg" ||
file.mimetype === "image/webp"
) {
cb(null, true);
} else {
cb(null, false);
}
};
app.use(
multer({ storage: storage, fileFilter: fileFilter }).array("images", 8)
);
I use multer in nodejs to handle multipart/formdata request and get the image file on the request like this :
import multer from "multer";
const upload = multer({
storage: multer.memoryStorage(),
limits: { fileSize: 1000000000, files: 2 },
});
app.post("/", upload.single("image"), (req, res , next) => {
const imageFile = req.file
dbx
.filesUpload({ path: "/image.png", contents: imageFile })
.then((response: any) => {
})
.catch((uploadErr) => {
});
}
)
The problem is I can't upload the image and it gives me error that it's a Buffer not an actual image . How can I generate the image from req.file then upload it without saving it on the disk ?
You can decode your data or change it's encoding but to convert it to an image doesn't make any sense.
The example code provided by dropbox here, reads a file inutf-8 and uploads it.
You can also do that same by taking the buffer and uploading it.
const imageFile = req.file.buffer;
Solved the issue by sending the file buffer itself to dropbox like this
const imageFile = req.file && req.file.buffer;
dbx
.filesUpload({ path: "/life.png", contents: imageFile })
.then((response: any) => {
console.log("SUccess");
})
.catch((uploadErr) => {
console.log("ERRRR");
console.log(uploadErr);
});
For some reason if I attempt to save an image through multer's storage, I get this error:
[Error: ENOENT: no such file or directory, open 'C:\MAMP\htdocs\Chat Backend\public\images\servers\1596819056816AFKay.jpg'] {
errno: -4058,
code: 'ENOENT',
syscall: 'open',
path: 'C:\\MAMP\\htdocs\\Chat Backend\\public\\images\\servers\\1596819056816AFKay.jpg',
storageErrors: []
}
My multer setup looks like this:
var multer = require('multer');
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'public/images/servers')
},
filename: (req, file, cb) => {
cb(null, Date.now() + file.originalname)
}
})
var fileFilter = (req, file, cb) => {
if (file.mimetype === 'image/png' || file.mimetype === 'image/jpg' || file.mimetype === 'image/jpeg') {
cb(null, true)
} else {
cb(null, false)
}
}
app.use(multer({ storage: storage, fileFilter: fileFilter }).single('image'));
If I were to not use storage and just stick to dest, it saves the image just fine.
app.use(multer({ dest: 'public/images/servers' }).single('image'));
I've checked a lot of similar questions but their problem is usually that the name of the image contains symbols which are not allowed, whereas that is not the case with me because I've tried the simplest names (just a string for example) and I still get the error. Why might this error be happening?
I was facing the same issue. I am on windows OS. This helped:
new Date().toISOString().replace(/:/g, '-') + file.originalname
FIXED: ( NO req.file ) ( YES req.files )
My project need multiple files upload,
If i single image upload working, multiple image upload working ( upload to files ) and i need req.file.filename because i write mysql this image road.
Req.File = Undefined..
// Sinle image upload and write mysql..
Router.post('/uax_items_addOne', Upload.single('fileUrl'), Controller.Cnt_AddOne);
// Multiple image upload and undefined req.file
Router.post('/uax_items_multipleFile', Upload.array('fileUrl', 12), Controller.Cnt_MultipleFile);
// This is controller
exports.Cnt_MultipleFile = (req, res, next) => {
console.log(req.file); // This is write "undefined"
}
// This is my Storage
const Storage = Multer.diskStorage({
destination: function(req, file, callback) {
callback(null, './uax_Uploads/images');
},
filename: function(req, file, callback) {
callback(null, 'img-' + Date.now() + Path.extname(file.originalname));
}
});
var Upload = Multer({
storage: Storage
});
Multiple files are provided to you in req.files (note the s at the end).
If you want to simplify your POST queries, I would recommend using Multer's .fields() function, that let you group incoming file params (post-processing is done, both, with the files field).
For example:
upload.fields([
{ name: 'one_tag_param' , maxCount: 1 },
{ name: 'multiple_tag_param' , maxCount: 12 }
])
I need to post an array of images and a single image for product preview.
Here my multer settings
const multer = require('multer');
// Multer settings
const storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, './uploads/');
},
filename: function(req, file, cb) {
cb(null, file.originalname);
}
});
const fileFilter = (req, file, cb) => {
// reject a file
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
cb(null, true);
} else {
cb(null, false);
}
};
const upload = multer({
storage: storage,
fileFilter: fileFilter
});
const multerSettings = upload.fields([{ name: 'thumb', maxCount: 1 }, { name: 'images', maxCount: 8 }]);
module.exports = multerSettings;
My model for posting data. I am using MongoDB
thumb: {
url: String
},
images: [{url: String}]
Client part
const fd = new FormData();
const { images, thumb } = state.details;
fd.append('thumb', thumb);
fd.append('images', images);
await this.$axios.post('/product', fd);
Images are an array of files [File, File, File], and for some reason, req.files['images'] is undefined on the server, but thumb works properly. And when I am sending the same data via postman all works as expected. In the browser in header preview i see the following data
thumb: (binary)
images: [{},{},{}]
Maybe images should be an array of binary data?
And when sending a single file like this
fd.append('images', images[0]);
req.files['images'] its work properly. I need somehow modify my array on the client. By i have no idea what i should do.
I would be grateful for any tips
The solution is pretty simple.
const fd = new FormData();
const { images, thumb } = state.details;
fd.append('thumb', thumb);;
for(let i = 0; i < images.length; i++) {
fd.append('images', images[i]);
}
await this.$axios.post('/product', fd);
const files = new FormData();
files.append('files', data);
const res = await httpApi.post('/user/upload', files, {headers: { 'Content-Type': 'multipart/form-data'}});
This works! :)