How to receive req.file from request form-data in node - node.js

I have two apis, I want to send a file from the first api using request and formData.
How to receive req.file from request form-data ?
Receive side code
var storage = multer.diskStorage({
destination: function (req, file, cb) {
mkdirp(configServer.dataDir+ "/tmp", function(err){
cb(null, configServer.dataDir+ "/tmp/")
})
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
})
var upload = multer({ storage: storage }).single('file');
exports.upload_in_server = function (req, res) {
upload(req, res, function (err) {
console.log("file : ", req.file)
console.log("body : ", req.body)
res.json({success: true})
})
}
router.post("/myurl/uploadInServer", UserController.upload_in_server);
Send side code
var storage2 = multer.diskStorage({
destination: function (req, file, cb) {
mkdirp(config.dataDir+ "/tmp", function(err){
cb(null, config.dataDir+ "/tmp/")
})
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
})
var upload2 = multer({ storage: storage2 }).single('file');
exports.user_coffre_fort_create_file2 = function (req, res) {
upload2(req, res, function (err) {
var obj = {
'Nom': "Lagaf",
'Prénom': "Vincent",
'Date de naissance': "13/01/1960",
'file':new Buffer(fs.readFileSync(req.file.path)).toString("base64")
}
request({
url: "/myurl/uploadInServer",
method: 'POST',
formData: obj,
headers: {"Content-Type": "application/x-www-form-urlencoded", "Authorization": token}
}, function (err, stdout, body) {
res.json({success:true})
})
})
}
This is what I receive
the req.file is null, and i received the file in the body
How to recevie the file in the req.file ?
Thanks in advance
file : undefined
body : {
'Nom: 'Lagaf',
'Prénom': 'Vincent',
'Date de naissance': '13/01/1960',
file:/9j/4gIcSUNDX1BST0ZJTEUAAQEAAAIMbGNtcwIQAABtbnRyUkdCIFhZWiAH3AABABkAA

You need to use multipart/form-data as content type for uploading files and form feature from requests module. Take a look at this answer.

Related

How can I send file to api that use multer in node js?

I want to send a file from a server to another server, using two apis, one that upload to the final server and one that read a form data and send it to an api that call the first api
Upload to final server
var storage = multer.diskStorage({
destination: function (req, file, cb) {
mkdirp(configServer.dataDir+ "/tmp", function(err){
console.log("err * : ", err)
if(err)
res.json({success:false, error:err})
cb(null, configServer.dataDir+ "/tmp/")
})
},
filename: function (req, file, cb) {
console.log("file**", file)
cb(null, file.fieldname + '-' + Date.now())
}
})
var upload = multer({ storage: storage }).single('file');
exports.upload_in_server = function (req, res) {
upload(req, res, function (err) {
console.log("body : ", req.body)
console.log("file : ", req.file)
if (err instanceof multer.MulterError) {
// A Multer error occurred when uploading.
console.log("err 1 : ", err)
} else if (err) {
// An unknown error occurred when uploading.
console.log("err 2 : ", err)
}
res.json({success: true})
})
}
router.post("/myurl/uploadInServer", UserController.upload_in_server);
In next, the api called to send the file to the final server
var storage2 = multer.diskStorage({
destination: function (req, file, cb) {
mkdirp(config.dataDir+ "/tmp", function(err){
console.log("err * : ", err)
if(err)
res.json({success:false, error:err})
cb(null, config.dataDir+ "/tmp/")
})
},
filename: function (req, file, cb) {
console.log("file**", file)
cb(null, file.fieldname + '-' + Date.now())
}
})
var upload2 = multer({ storage: storage2 }).single('file');
exports.user_coffre_fort_create_file2 = function (req, res) {
var querystring = require('querystring');
upload2(req, res, function (err) {
if (err instanceof multer.MulterError) {
// A Multer error occurred when uploading.
console.log("err 1 : ", err)
} else if (err) {
// An unknown error occurred when uploading.
console.log("err 2 : ", err)
}
var FormData = require('form-data');
var form = new FormData();
const encoded = req.file.toString('base64')
form.append('file', encoded);
form.append('Name', "Lagaf");
form.append('Surname', "Vincent");
form.append('birthdate', "13/01/1960");
request({
url: "/myurl/uploadInServer",
method: 'POST',
json: querystring.stringify(form),
headers: {"Content-Type": "application/x-www-form-urlencoded", "Authorization": my_tokentoken}
//
}, function (err, stdout, body) {
res.json({success:true})
})
})
}
This is what I receive in server, the body is not correct, and the file is undefined
body : { '"_overheadLength': '420',
_valueLength: '37',
writable: 'false',
readable: 'true',
dataSize: '0',
maxDataSize: '2097152',
pauseStreams: 'true',
_released: 'false',
_streams:
[ '----------------------------081543624686364985445462\r\nContent-Disposition: form-data; name="file"\r\n\r\n',
'[object Object]',
'',
'----------------------------081543624686364985445462\r\nContent-Disposition: form-data; name="Name"\r\n\r\n',
'Lagaf',
'',
'----------------------------081543624686364985445462\r\nContent-Disposition: form-data; name="Surname"\r\n\r\n',
'Vincent',
'',
'----------------------------081543624686364985445462\r\nContent-Disposition: form-data; name="birthdate"\r\n\r\n',
'13/01/1960',
'' ],
_currentStream: '',
_boundary: '--------------------------081543624686364985445462"' }
files : undefined
How to have a correct body and 'req.file' that is not undefined.
Is there any reason you converting binary file to a base64-encoded string? And why urlencoded is used instead of multipart/form-data?
Try:
request({
url: "/myurl/uploadInServer",
method: 'POST',
formData : {
file: req.file,
'Name': 'Lagaf',
'Surname': 'Vincent',
'birthdate': '13/01/1960'
},
headers: {
"Content-Type": "multipart/form-data"
"Authorization": my_tokentoken
}
}, function (err, stdout, body) {
res.json({success:true})
})

express body-parser and multer value receiving issue?

I am giving post request /product/create with some value and an image.
if I console every value before
upload(req, res, (err) => {})
it is showing properly with out image info.
if I receive the value after upload(req, res, (err) => {})
No value is showing.
Full post request code:
app.post('/product/create', (req, res) => {
let filename;
upload(req, res, (err) => {
if(err){
res.render('index', {
msg: err
});
} else {
if(req.file == undefined){
res.render('index', {
msg: 'Error: No File Selected!'
});
} else {
res.render('index', {
msg: 'File Uploaded!',
filename = req.file.filename;
});
}
}
});
const product = {
title : req.body.title,
desc : req.body.desc,
image : filename,
}
});
configuring Multer:
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,
limits:{fileSize: 1000000},
fileFilter: function(req, file, cb){
checkFileType(file, cb);
}
}).single('myImage');
function checkFileType(file, cb){
const filetypes = /jpeg|jpg|png|gif/;
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
const mimetype = filetypes.test(file.mimetype);
if(mimetype && extname){
return cb(null,true);
} else {
cb('Error: Images Only!');
}
}
Multer does not support 'req.file.filename' outside upload function. As filename, originalname, fieldname etc is inbuild API of multer. It is limited to upload function only.
Now, if you are trying to upload product values inside database then you have to create an insert function inside multer upload function only.

not able to upload file using multer

I have seen many answers on this and tried almost all of it but none seems to work for me. I can print the form data as ascii chars but I don't see the file stored in the public/uploads folder as expected. I can read and render stored files on react app using API but can't upload it. I get no errors, everything works fine but no file is uploaded in the folder. I'm trying to upload a file using multer and below are the code snippets :
routes/uploads.js
var storage = multer.diskStorage({
dest : function (req, file, cb) {
cb(null, path.join(__dirname, 'public/uploads/'))
}
});
var upload = multer({storage:storage}) ;
router.post('/upload', upload.single('mypic'), function (req, res, next) {
console.log("inside upload files");
console.log(req.body); //prints non-readable characters as I am uploading image as expected
console.log(req.file); //says undefined
return res.status(204).end();
});
API.js (React side):
export const uploadFile = (payload) => //payload is actually formdata
fetch(`${api}/files/upload`,
{
method: 'POST',
//headers: { 'Content-Type': 'application/json' },
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
},
body: payload
}
)
.then(res => {
console.log(res);
return res.status;
})
.catch(error => {
console.log(error);
return error;
});
Try below IT contains multiple parts:
var storage = multer.diskStorage({
destination: function (req, file, cb) {
const extension = file.mimetype.split('/')[1];
//you can change destination runtime
if(file.fieldname == "covers[]")
{
cb(null, __dirname, '../public/uploads/cover');
return;
}
else
{
cb(null, '../public/uploads/image');
return;
}
},
filename: function (req, file, cb) {
//you can also change name
cb(null, filename)
}
});
var upload = multer({
storage: storage,
});
Try removing :
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'

Rename uploaded images using MULTER

I am uploading the images using multer. They all are given random names (dec93b9f333c7a731723b06ce73c0bbc.jpg), which is very bad for SEO... Can you guys help me out, how to save the images with the pattern: 'fixed-name'+'random-name'.extension. Then at least part of the file would be readable for the google. Thanks!
app.set('images', '/var/www/images');
app.use(app.get('images'), express.static(app.get('images')));
var multerForImage = multer({
dest: app.get('images'),
onParseStart: function (file) {
console.log("Started parsing file stream", file);
},
onFileUploadStart: function (file) {
console.log('File recieved: ', file.originalname);
},
onFileUploadComplete: function (file, req, res) {
console.log("File upload complete");
var path = app.get('images') + "/" + file.name;
var user = req.session.user;
res.json({
success: true,
data: path
});
},
onFileUploadData: function (file, data, req, res) {
console.log('Data recieved for file upload');
},
onParseEnd: function (req, next) {
console.log("Parsing data end for file upload");
}
});
You can use the storage configuration.
app.set('images', '/var/www/images');
app.use(app.get('images'), express.static(app.get('images')));
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, app.get('images'))
},
filename: function (req, file, cb) {
const randomPart = uuidV4(); // use whatever random you want.
const extension = file.mimetype.split('/')[1];
cb(null, 'fixed-name'+ randomPart + `.${extension}`)
}
})
var multerForImage = multer({
storage: storage,
...

Upload image + duplicate(low-res thumbnail) via multerjs

I am building a webapplication that allows users to upload an avatar. However, in addition to the avatar I want to create a thumbnail low-res (e.g. 64 x 64) and store it on my server. Currently I'm using this code to store the image in two directories, but it's the same resolution in both directories. How would I store a different resolution in the thumbnails directory?
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads/thumbs');
callback(null, './uploads');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
}
});
You can use sharp for resize you images in your router:
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, './uploads')
},
filename: (req, file, cb) => {
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
}
})
and:
router.post('/', upload.single('image'), async (req, res) => {
try {
const { filename: image } = req.file
await sharp(req.file.path, { failOnError: false })
.resize(64, 64)
.withMetadata()
.toFile(
path.resolve(req.file.destination, './thumbs', image.replace(/\.(jpeg|png)$/, `.jpg`))
)
fs.unlink(req.file.path)
return res.json({
thumb_url: '/uploads/thumbs/' + image.replace(/\.(jpeg|png)$/, `.jpg`)
});
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error!');
}
});
fs.unlink(req.file.path) remove your orginal image from ./uploads

Resources