Reading png image from request using body-parser and Express - node.js

I am sending the following request to my server using postman:
I try to access the image in my application using the following code:
app.js
var express = require('express');
var bodyParser = require('body-parser');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
app.use(bodyParser.raw({
type: 'image/png',
limit: '10mb'
}));
app.use('/', indexRouter);
app.use('/users', usersRouter);
module.exports = app;
index.js (router)
var express = require('express');
const router = express.Router();
var Jimp = require('jimp');
/* GET home page. */
router.get('/', function(req, res) {
res.render('index', { title: 'Express' });
});
router.post('/a', function(req, res) {
var image = req.body;
try{
Jimp.read(image, (err, input) => {
if (err) throw err;
input.sepia();
input.getBuffer(Jimp.AUTO, (err, output) => {
if(err) throw err;
res.writeHead(200, {'Content-Type': 'image/png' });
return res.end(output, 'binary');
});
});
}catch (err){
return res.status(400).send(`Error: ${err.message}`).end();
}
});
module.exports = router;
I was first using a form (with the help of express-fileupload library) to send the image and this worked fine, so I know the problem has to be somewhere before the line var image = req.body.
For the Jimp functions (image processing library) to work, the image has to be a buffer representing the png image.
When running console.log(image), the console outputs {}.
Can anybody show me a way to read the png as a buffer when it is sent as a Binary file?

Nevermind, I just had to change the Content-Type header in my request to image/png -.-

can you rewrite function with lib multer?
const multer = require('multer')
const storage = multer.memoryStorage()
const upload = multer({ storage: storage })
router.post('/a', upload.single('image'), function(req, res, next) {
const image = req.file.buffer
});
or with formidable?
var formidable = require('formidable' );
router.post('/a', (req, res) => {
const form = new formidable.IncomingForm();
form.parse(req, (error, fields, files) => {
const image = files.image;
})
});

Related

how to read posted data on node js api

i want to read the csv data uploaded to backened.
for this i am sending the data via post from front end..
frontend code:
fileEvent(e) {
this.filedata = e.target.files;
if (this.filedata.length > 0) {
const file: File = this.filedata[0];
console.log(file);
const formData: FormData = new FormData();
formData.append('files', file, file.name);
this.http.post('myUrl', {file: formData}, this.options)
.subscribe((res) => {
});
}
}
screenshot of my file:
now on backened i have written route on api.js that directs me
to the controller i have created.
my api.js code:
router.post('/product/csvdata', function (req, res) {
productimport.importcsvProduct(req, res);
});
and finally on my controller i am consoling my data:
var product = {
importcsvProduct: function (req,res) {
console.log(req.body.file);
}
};
module.exports = product;
but i am getting empty {} in console..??
can anyone check whats wrong with this..??
You need to use a file handling middleware in this case, such as multer.
const express = require('express')
const multer = require('multer')
const upload = multer({ dest: 'uploads/' })
const app = express()
app.post('/profile', upload.single('csvdata'), function (req, res, next) {
// req.file is the `csvdata` file
// req.body will hold the text fields, if there were any
})

Sending file from one node js server to another

So on first server I have route like this:
const express = require('express');
const router = express.Router();
const FormData = require('form-data');
const fetch = require('node-fetch');
const multer = require('multer');
const storage = multer.memoryStorage();
const upload = multer({ storage });
router.post('/', upload.single('file'), async (req, res) => {
const form = new FormData();
form.append('folderId', req.body.folderId);
form.append('file', req.file.buffer, req.file.filename);
const result = await fetch('http://localhost:3003/users', { method: 'POST', body: form }).then(res => res.json());
res.json(result);
})
On this server, it works fine, I can see req.file and it's buffer. So I wanna send this file (without storing it on first server, it exists only in memory and as buffer) to another.
Other server route is like this:
const express = require('express');
const router = express.Router();
const multer = require('multer');
const path = require('path');
const putanja = path.join(__dirname, '../uploads/users');
const storage = multer.diskStorage({
destination: (req, file, cb) => {
console.log('entered here?')
if (!req.body.folderId) return cb({ message: 'no folderId' });
if (!fs.existsSync(putanja + '/' + folderId)) fs.mkdirSync(putanja + '/' + folderId);
cb(null, putanja + '/' + folderId);
},
filename: (req, file, cb) => cb(null, file.originalname)
});
const upload = multer({ storage });
const fs = require('fs');
router.post('/', upload.single('file'), async (req, res) => {
console.log(req.body)
console.log(req.file)
res.json({ status: 'ok' })
})
So on second server, it doesn't even enter the multer middleware, req.file is always defined, and that console.log('entered here?') is never seen. Looks like I'm not passing data as multipart-form?
Also, second server, when sending file directly to it via postman, works.
So my question, how do I send that file? As a buffer? Stream? Base64? I think I tried everything, even changed node-fetch to request, but still no luck.
So on second server, it doesn't even enter the multer middleware, req.file is always defined, and that console.log('entered here?') is never seen. Looks like I'm not passing data as multipart-form?
So this mean your second server doesn't understand the Content-Type of request.
So do one thing add Content-Type parameter in header when you are sending request to second server
Add Content-Type to multipart/form-data
or if you don't know pass headers : {
'Content-Type' : undefined
} http will set header for you
You send your request to /users (http://localhost:3003/users) yet your second server expects the request on /.
Try changing either one to match the other.
'use strict';
const express = require('express');
const multer= require('multer');
const concat = require('concat-stream');
const request = require('request');
const router = express.Router();
function HttpRelay (opts) {}
HttpRelay.prototype._handleFile = function _handleFile (req, file, cb) {
console.log('hell0 proto');
file.stream.pipe(concat({ encoding: 'buffer' }, function (data) {
const r = request.post('/Endpoint you want to upload file', function (err, resp, body) {
if (err) return cb(err);
req.relayresponse=body;
cb(null, {});
});
const form = r.form();
form.append('uploaded_file', data, {
filename: file.originalname,
contentType: file.mimetype
});
}))
};
HttpRelay.prototype._removeFile = function _removeFile (req, file, cb) {
console.log('hello');
cb(null);
};
const relayUpload = multer({ storage: new HttpRelay() }).any();
router.post('/uploadMsgFile', function(req, res) {
relayUpload(req, res, function(err) {
res.send(req.relayresponse);
});
});
module.exports = router;

How to upload and download a file in a single service call in nodejs?

I can upload a file via postman and download a file from server in two different service .. But what i need is ..In a single call i should able to upload the file to server ,then perform some operation after performing some operation i should able to download the file automatically.
Here is my code.
My firsts service(file upload operation)
var express = require('express');
var fs = require('fs');
var formidable = require('formidable');
var router = express.Router();
/* GET home page. */
router.post('/', function(req, res, next) {
var form = new formidable.IncomingForm();
form.uploadDir="./file"
form.keepExtensions=true;
form.maxFileSize=10*1024*1024;
form.multiples=false;
form.parse(req, function (err, fields, files) {
res.write('File uploaded');
res.end();
});
});
module.exports = router;
Download service
var express = require('express');
var router = express.Router();
var express = require('express');
router.get('/', function(req, res, next) {
var file = './file/myOutput.txt';
var name = 'ENC.txt'
res.download(file, name);
});
module.exports = router;
Now i need to make this two service as one?
var express = require('express');
var formidable = require('formidable');
var app=express();
async function calculation(parameters)
{
if(parameters)
{
//Here you can do calculation depending upon parameter values
}
else
{
//Display error or as per your choice
}
}
app.get('/',function(req,res){
res.sendFile(__dirname+'/index.html');
});
async function cal(res,file,form)
{
try{
const data = await calculation(true)
if(data){
res.set({
'Location' : __dirname+'/index.html',
});
res.download( __dirname+file.name);
}
}
catch(error)
{
console.log(error);
}
}
app.post('/',function (req,res){
var form = new formidable.IncomingForm();
form.parse(req);
form.on('fileBegin',function(name,file){
file.path = __dirname+file.name;
console.log("Uploading");
});
form.on('file',
function(name,file)
{
console.log('Uploaded ',file.name);
cal(res,file);
});
});
Hope it helps

How to add location path to Mysql DB with using Multer in Node.JS

I'm new in Node.JS development. Recently I've struggling that problem: I want to upload photo to in "/uploads" directory in my project. I've added photo alone. But when its come to adding photo server and save its location path with photos owner id and description to Mysql DB I didn't make it. I know that Multer only accept multipart-form data.
Here is my Node.Js code
var models = require('../../models');
var express = require('express');
var router = express.Router();
var multer = require('multer');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json({limit:'50mb'}));
app.use(bodyParser.urlencoded({extended:true, limit:'50mb'}));
const uuidv1 = require('uuid/v1');
var owner_id;
var description;
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/')
},
filename: function (req, file, cb) {
const photo_id = uuidv1();
cb(null, photo_id + '.jpg');
addPhotoToDb(photo_id,owner_id,description);
}
});
function addPhotoToDb(photo_id,owner_id,description) {
models.PHOTOS.create({
photo_id: photo_id,
description: description,
owner_id: owner_id,
location_path: 'uploads/' + photo_id + '.jpg'
})
}
var upload = multer({ storage: storage }).single('photo');
router.post('/upload', function (req, res) {
//This part is problematic I tried so many things
//owner_id=req.files
//description=req.files
upload(req, res, function (err) {
if (err) {
}
res.json({
success: true,
message: 'Image uploaded!'
});
})
});
module.exports = router;
Also in Postman I'm sending request like that:
https://i.stack.imgur.com/04Qz1.png
In your screenshot you show the "body" tab. In the left there is the "headers" tab. Click on it and check that you have the content-type set to "multipart/form-data" because multer won't process any data that aren't on this content type.

Trying to upload a file to a nodejs web service

I'm trying to create a simple web service in nodejs that accepts a file and saves it.
Here is my code.
var express = require('express');
var app = express();
var fs = require('fs');
var sys = require('sys');
app.listen(8080);
app.post('/upload', function(req, res) {
console.log(req.files);
var fileKey = Object.keys(req.files)[0];
var file = req.files[fileKey];
fs.readFile(file.path, function(err, data) {
fs.writeFile(__dirname, data, function(err) {
res.redirect("back");
});
});
});
I'm using fiddler to upload the file.
console.log(req.files);
gives undefined. An exception is also thrown:
Object.keys called on non-object
Any idea what I may be doing wrong?
You don't seem to be using the bodyParser middleware which is required to parse uploads (amongst other things):
app.use(express.bodyParser());
app.post('/upload', function(req, res) { ... });

Resources