Formidable doesnt form.parse() when uploading a file in Nodejs - node.js

When i send a file to /upload, from the terminal I can see that the code is blocked at form.parse(req... On the Internet I read that this is because I use bodyParser(), and people suggested to do this:
delete express.bodyParser.parse['multipart/form-data'];
however when I do that my code crashes since parse is null.
Anyone has any idea on how to get file upload working only in /upload and possibly with formidable?
Thanks.
This is my app.js:
'use strict';
var express = require("express");
var async = require("async");
var http = require('http');
var url = require("url");
var qs = require("querystring");
var fs = require("fs");
var formidable = require("formidable");
var mime = require("mime");
var app = module.exports = express();
app.configure(function () {
app.set("views", __dirname + "/views");
app.set("view engine", "ejs");
app.engine("html", ejs.renderFile);
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser("abc"));
app.use(express.static(__dirname + "/static"));
app.use(app.router);
app.use(express.limit('5mb'));
});
app.post('/upload', storage.upload);
This is my code storage.js:
'use strict';
var async = require('async');
var formidable = require('formidable');
var fs = require('fs');
var util = require('util');
var api = require('./common');
exports.upload = function (req, res) {
console.log("I am here");
var form = new formidable.IncomingForm(),
files = [],
fields = [];
form.uploadDir = "./uploads";
form
.on('field', function (field, value) {
console.log(field, value);
fields.push([field, value]);
})
.on('error', function (err) {
res.writeHead(200, {'content-type': 'text/plain'});
res.end('error:\n\n'+util.inspect(err));
})
.on('file', function (field, file) {
console.log(field, file);
files.push([field, file]);
})
.on('aborted', function (err) {
console.log("user aborted upload");
})
.on('end', function () {
console.log('-> upload done');
res.writeHead(200, {'content-type': 'text/plain'});
res.write('received fields:\n\n '+util.inspect(fields));
res.write('\n\n');
res.end('received files:\n\n '+util.inspect(files));
});
form.parse(req);
};

If you want to use formidable then, remove app.use(express.bodyParser());
& add app.use(express.json());app.use(express.urlencoded());
Connect 3.0
This solution worked for me, it might be helpful for other dev.

Have you seen the example on github: https://github.com/visionmedia/express/blob/master/examples/multipart/index.js
I've modified it to run on Express 3.x and it seems to work smoothly:
var express = require('express');
var fs = require('fs');
var app = express();
var format = require('util').format;
// bodyParser in connect 2.x uses node-formidable to parse
// the multipart form data.
app.use(express.bodyParser())
app.get('/', function(req, res){
res.send('<form method="post" enctype="multipart/form-data">'
+ '<p>Title: <input type="text" name="title" /></p>'
+ '<p>Image: <input type="file" name="image" /></p>'
+ '<p><input type="submit" value="Upload" /></p>'
+ '</form>');
});
app.post('/', function(req, res, next){
// the uploaded file can be found as `req.files.image` and the
// title field as `req.body.title`
res.send(format('\nuploaded %s (%d Kb) to %s as %s'
, req.files.image.name
, req.files.image.size / 1024 | 0
, req.files.image.path
, req.body.title));
});
if (!module.parent) {
app.listen(3000);
console.log('Express started on port 3000');
}

Related

Getting input data from text field in Nodejs

I'm sure this has already been answered but I can't find the exact question I'm looking for.
I have an ejs file that has this for the form.
<form action="" method="POST">
<div class="input-group">
<input type="text" class="form-control" name="userSearchInput" placeholder="Enter the id of the product you would like to buy" aria-label="Recipient's username" aria-describedby="basic-addon2">
<div class="input-group-append">
<button class="btn btn-outline-secondary" id="searchBTN" type="submit"><i class="fas fa-cart-plus mr-2"></i>Add to Cart</button>
</div>
</div>
</form>
On the node side in my app.js file, I've installed and downloaded both express and body-parser and done the requisite require function.
var bodyParser = require('body-parser');
var express = require('express');
var app = express();
I've set up my middleware for body-parser here:
// middleware for bodyParser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
Then, to get the content of what the user types into the input text box, I'm using this:
app.post('/', function(req, res) {
var item = req.body.userSearchInput;
console.log(item);
});
This is my first time using app.post and since nothing is being console logged- I'm not sure where I'm going wrong.
full app.js file
var express = require('express');
var path = require('path');
var http = require('http');
var mysql = require('mysql');
var bodyParser = require('body-parser');
var nodemon = require('nodemon');
var app = express();
var port = process.env.PORT || 3000;
// setting up views
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
// middleware for bodyParser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
// create connection to mySQL db
var connection = mysql.createConnection ({
host : 'localhost',
user : 'root',
password : 'root',
database : 'bamazon'
});
// initialize connection
connection.connect();
// run db query and print items to index html home page
connection.query('SELECT * from products', function (error, results) {
if (error) throw error;
console.log(results);
app.get('/', function(req, res){
res.render('index', {list: results});
})
});
app.post('/', function(req, res) {
var item = req.body.userSearchInput;
console.log(item);
});
// setting up listen for server function
app.listen(port, function (err) {
if (err) throw err;
console.log("Server is running on port " + port);
});
use
<form action="/" method="post">
Firstly add form action in your ejs file like action="/search".Step 2: try with app.post('/search'
Works fine i just commented out db connections only.
may be try this app.js file with new express project.
Run command node app instant of npm start
var express = require('express');
var path = require('path');
var http = require('http');
var bodyParser = require('body-parser');
// var nodemon = require('nodemon');
// var mysql = require('mysql');
var app = express();
var port = process.env.PORT || 3000;
// setting up views
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
// middleware for bodyParser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
/*
create connection to mySQL db
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'root',
database: 'bamazon'
});
// initialize connection
connection.connect();
// run db query and print items to index html home page
connection.query('SELECT * from products', function (error, results) {
if (error) throw error;
console.log(results);
});
*/
app.get('/', function (req, res) {
res.render('index', { list: [], title:"salman" });
})
app.post('/', function (req, res) {
var item = req.body.userSearchInput;
console.log(item);
});
// setting up listen for server function
app.listen(port, function (err) {
if (err) throw err;
console.log("Server is running on port " + port);
});

Express body-parser request.body returning undefined

when i run this app and submit the form 'console.log(request.body)' returning undefined. i am a beginner in node js . can anyone please explain what i am doing wrong?
this is the registration form
register.jade
doctype html
html
head
title.
Fonebook
link(rel='stylesheet', href='/assets/bootstrap/css/bootstrap.min.css')
script(src='https://code.jquery.com/jquery-2.2.0.min.js')
script(src='/assets/bootstrap/js/bootstrap.min.js')
body
div.container
h3.
The Fonebook
form(method="POST",class="center",id="regForm",action='/doReg',enctype="multipart/form-data")
div.panel.panel-info
div.panel-heading.
Registration
div.panel-body
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
label.
Profile Picture:
input(type='file',name='proPic')
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
label.
Email:
input.form-control(id="email", type="email", name="email", placeholder="Enter email ")
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
label.
Name:
input.form-control(id="name", type="text", name="name", placeholder="Enter name ")
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
label.
Password:
input.form-control(id="password", type="password", name="password")
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
a(href='login').
Already have an account?
div.panel-footer
button.btn.btn-info(type="submit").
Register
here is my app.js file
var express = require('express');
var app = express();
var mongoose = require('mongoose');
mongoose.connect('mongodb://127.0.0.1/test');
var uploadDir = __dirname + '/uploads';
var fs = require('fs');
var multer = require('multer');
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
var conn = mongoose.connection;
app.set('views', './views');
app.set('view engine', 'jade');
app.use('/assets', express.static(__dirname + '/public'));
var port = process.env.PORT || 3000;
app.all('/', function (req, res) {
res.render('login');
})
app.all('/register', function (req, res) {
res.render('register');
})
app.all('/login', function (req, res) {
res.render('login');
})
var storage = multer.diskStorage({
destination: function (request, file, callback) {
callback(null, uploadDir);
},
filename: function (request, file, callback) {
//console.log(file);
callback(null, Date.now() + '.jpg');
}
});
var upload = multer({storage: storage}).single('proPic');
app.all('/doReg', function (request, response) {
upload(request, response, function (err) {
if (err) {
console.log(err);
return;
}
//console.log(request.file);
response.end('Your File Uploaded');
})
console.log(request.body);
});
app.listen(port);
body-parser does not support multipart forms.
From their README
This does not handle multipart bodies, due to their complex and typically large nature. For multipart bodies, you may be interested in the following modules:
busboy and connect-busboy
multiparty and connect-multiparty
formidable
multer
Seeing as you're already using multer you can access your fields this way:
app.all('/doReg', upload, function (request, response) {
console.log(request.body);
});

String Compression in Node.JS

I'm using the following code to make GET request and to store the result in the local variable using node.js, the result stored in the variable is intended to send as sms. How do I compress the data stored in the result prior to sending it as sms? Please help
var express = require('express');
var request = require("request")
var app = express();
app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));
app.get('/', function(request, response) {
response.send('Hello Cruel World!');
});
var bodyParser = require('body-parser');
var WEBHOOK_SECRET = "my secret here";
app.post('/telerivet/webhook',
bodyParser.urlencoded({ extended: true }),
function(req, res) {
var secret = req.body.secret;
if (secret !== WEBHOOK_SECRET) {
res.status(403).end();
return;
}
if (req.body.event == 'incoming_message') {
var content = req.body.content;
var from_number = req.body.from_number;
var phone_id = req.body.phone_id;
}
request("http://boilerpipe-web.appspot.com/extract?url=http: //"+content+"&extractor=LargestContentExtractor&output=text&extractImages=", function(error, response, data) {
// do something with the message, e.g. send an autoreply
res.json({
messages: [
{ content:" " + data}
]
});
res.status(200).end();
});
}
);
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
Assuming you want to compress the response to the browser, you will likely want to add a GZIP middleware package:
var compress = require('compression');
app.use(compress());

node.js file upload typeError Can not read property 'image'

I am using this program example to upload a image into uploads/fullsize directory.
The application is running but if I try to upload a image I am getting the following failure:
TypeError: Cannot read property 'image' of undefined at Object.handle
(/Users/machupicchu/Desktop/test/app.js:46:23) at next_layer
(/Users/machupicchu/Desktop/test/node_modules/express/lib/router/route.js:103:13)
at Route.dispatch
(/Users/machupicchu/Desktop/test/node_modules/express/lib/router/route.js:107:5)
at c
(/Users/machupicchu/Desktop/test/node_modules/express/lib/router/index.js:195:24)
at Function.proto.process_params
(/Users/machupicchu/Desktop/test/node_modules/express/lib/router/index.js:251:12)
at next
(/Users/machupicchu/Desktop/test/node_modules/express/lib/router/index.js:189:19)
at next
(/Users/machupicchu/Desktop/test/node_modules/express/lib/router/index.js:166:38)
at next
(/Users/machupicchu/Desktop/test/node_modules/express/lib/router/index.js:166:38)
at Layer.staticMiddleware [as handle]
(/Users/machupicchu/Desktop/test/node_modules/express/node_modules/serve-static/index.js:55:61)
at trim_prefix
(/Users/machupicchu/Desktop/test/node_modules/express/lib/router/index.js:226:17)
The application looks like this:
var express = require('express');
var bodyParser = require('body-parser');
var path = require ('path');
var port = 3000;
var fs = require('fs');
//var collection;
//dataExt = require('./routes/serverExtend');
// setup middleware
var app = express();
app.use(bodyParser());
app.use(express.static(__dirname + '/public')); //setup static public directory
app.set('views', __dirname + '/views'); //optional since express defaults to CWD/views
app.set('view engine', 'ejs');
// Start server
app.listen(port);
console.log('App started on port ' + port);
var form = "<!DOCTYPE HTML><html><body>" +
"<form method='post' action='/upload' enctype='multipart/form-data'>" +
"<input type='file' name='image'/>" +
"<input type='submit' /></form>" +
"</body></html>";
app.get('/', function (req, res){
res.writeHead(200, {'Content-Type': 'text/html' });
res.end(form);
});
app.get('/uploads/fullsize/:file', function (req, res){
file = req.params.file;
var img = fs.readFileSync(__dirname + "/uploads/fullsize/" + file);
res.writeHead(200, {'Content-Type': 'image/jpg' });
res.end(img, 'binary');
});
/// Post files
app.post('/upload', function(req, res) {
fs.readFile(req.files.image.path, function (err, data) {
var imageName = req.files.image.name
/// If there's an error
if(!imageName){
console.log("There was an error")
res.redirect("/");
res.end();
} else {
var newPath = __dirname + "/uploads/fullsize/" + imageName;
/// write file to uploads/fullsize folder
fs.writeFile(newPath, data, function (err) {
/// let's see it
res.redirect("/uploads/fullsize/" + imageName);
});
}
});
});
Can someone help me why I am getting the TypeError??
Also created my directory where the files should be save.
app.js
uploads -> fullsize -> images.jpg
You need multipart middleware for your file upload to work as body-parser does not provide it.
First, add this to the top of your app:
var multipart = require('connect-multiparty');
Next, edit your post route slightly:
app.post('/upload', multipart(), function(req, res) {
// ...
}
Now req.files should now be avaiable to you in your POST /upload route.

TypeError: Cannot read property 'image' of undefined

There is something wrong in my source code but I'm not able to figure out what - please help. I was looking for some solutions found some and updated source code according them but didn't help.
var express = require('express');
var fs = require('fs');
var bodyParser = require('body-parser');
var app = express()
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
var form = "<!DOCTYPE HTML><html><body>" +
"<form method='post' action='/upload' enctype='multipart/form-data'>" +
"<input type='file' name='image' id='image'/>" +
"<input type='submit' /></form>" +
"</body></html>";
app.get('/', function(req, res){
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(form);
});
app.post('/upload', function(req, res){
fs.readFile(req.files.image.path, function(err, data){
var imageName = req.files.image.name
if(!imageName){
console.log("There was an error");
res.redirect('/');
res.end();
}else{
var newPath = __dirname + "/uploads/fullsize/" + imageName;
fs.writeFile(newPath, data, function(err){
res.redirect("/uploads/fullsize/" + imageName);
});
}
});
});
app.listen(8080);
The body-parser middleware does not handle multipart bodies.
From the body-parser github:
This does not handle multipart bodies, due to their complex and typically large
nature. For multipart bodies, you may be interested in the following modules:
busboy and connect-busboy
multiparty and connect-multiparty
formidable
multer
https://github.com/expressjs/body-parser

Resources