POST Request Issue in ExpressJS - javascript

I'm working with NodeJS and I'm working on letting users upload files. Right now though I'm having a lot of problem even trying to get a simple POST request.
Over in my index.ejs file I have some code that creates a form and then sends a post request:
<div id="uploaddiv">Upload things here<br>
<form action="/upload" enctype="multipart/form-data" method="post">
<input type="text" name="title"><br>
<input type="file" name="upload" multiple="multiple"><br>
<input type="submit" value="Upload">
</form>
</div>
Then in server.js, I have code that handles the uploading.
var server = express.createServer();
//bunch of stuff left out
server.get('/upload', function(req, res) {
console.log("uploading!");
if (req.method.toLowerCase() == 'post') {
res.write('lol');
}
});
My problem is that navigating directly to localhost/upload will console.log properly, but clicking on the button gives me the error "Cannot POST /upload".
Thanks!

server.get means handle an HTTP GET. You want server.post. FYI the "Cannot XXX /uri" error is what express responds with when no active route matches the request and no 404 error handler has been configured.

By using server.get(), you're instructing that route to only respond to GET requests, but the form is obviously a POST.
You should use server.post().
You can also use server.any() if you want to it respond to both GET and POST (and every other HTTP verb as well).

You should probably use Felix Geisendörfer's node-formidable to upload files.
var express = require('express'),
app = express.createServer(),
util = require('util'),
formidable = require('formidable');
app.get('/upload', function (req, res){
res.writeHead(200, {'content-type': 'text/html'});
res.end(
'<form action="/upload" enctype="multipart/form-data" method="post">'+
'<input type="text" name="title"><br>'+
'<input type="file" name="upload" multiple="multiple"><br>'+
'<input type="submit" value="Upload">'+
'</form>');
});
app.post('/upload', function (req, res) {
var form = new formidable.IncomingForm();
form.uploadDir = '.';
form.keepExtensions = true;
form.parse(req, function(err, fields, files) {
res.writeHead(200, {'content-type': 'text/plain'});
res.write('received upload:\n\n');
res.end(util.inspect({fields: fields, files: files}));
});
return;
});
app.listen(3000, '127.0.0.1');
It is just a simple as this to do file uploading thanks to node-formidable.

Related

ERR_EMPTY_RESPONSE error using multiparty package in Node.js

I'm a newbie in Node.js and trying to upload an image from my html. I created the button which can upload image to my web app by using below html code.
<li><a onclick="getFile()" style="cursor:pointer; color:#000000;">Choose File</a></li>
<li><a onclick="uploadFile();" style="cursor: pointer; color:#000000;">Upload</a></li>
<li><a onclick="save2()" id="imageSave" style="cursor:pointer; color:#000000;">Save</a></li>
<li>Back to view</li>
<form action="/upload", method="post", enctype="multipart/form-data">
<div style='height:0px; width:0px; overflow:hidden;'><input type="file" name="upFile" id="upFile" onchange="getCmaFileView(this, 'name')" target="dropzone_1"/></div>
<div style='height:0px; width:0px; overflow:hidden;'><input type="submit" name="Upload" id="Upload" /></div>
</form>
After clicking upload li it uploads an image from node.js by using multiparty package like code below.
app.post('/upload', function(req, res, next) {
var form = new multiparty.Form();
// get field name & value
form.on('field',function(name,value){
console.log('normal field / name = '+name+' , value = '+value);
});
// file upload handling
form.on('part',function(part){
var filename;
var size;
if (part.filename) {
filename = part.filename;
size = part.byteCount;
}else{
part.resume();
}
console.log("Write Streaming file :"+global_username);
var writeStream = fs.createWriteStream('/opt/work/files/'+global_username);
writeStream.filename = filename;
part.pipe(writeStream);
part.on('data',function(chunk){
console.log(global_username+'.png'+' read '+chunk.length + 'bytes');
});
part.on('end',function(){
console.log(global_username+'.png'+' Part read complete');
writeStream.end();
});
});
// all uploads are completed
form.on('close',function(){
res.status(200);
});
// track progress
form.on('progress',function(byteRead,byteExpected){
console.log(' Reading total '+byteRead+'/'+byteExpected);
});
form.on('error',function(){
console.log('error');
});
form.parse(req);
});
It saves an image and uploads well, but it shows me an ERROR after waiting a while with ERR_EMPTY_RESPONSE message.
I think it is because of response. it means that after header goes post, should give it back response but it doesn't.
And actually, I wrote code that it gives response back in above code of Node.js
form.on('close',function(){
res.status(200);
});
However, it still gives same error... I don't know why.
Does anybody have an idea? or am I wrong?
You don't return response to client res.status(200) sets status to response then you need to call res.send()

uploading image with express js in openshift and getting the url of uploaded image

I am working on user profile in express where i need to upload user image. i have searched a lot but didn't get much info about this.
so this is so far i have done.
My profile view code:-
<form method="post" name="profileform" class="profileform" enctype="multipart/form-data" action="">
<div class="form-group">
<label for="UserProfilePicture">Profile Picture:</label>
<input type="file" class="form-control" id="UserProfilePicture" class="UserProfilePicture disbalefield" name="file" placeholder="Click to add Profile Pic"></div>
<input type="submit" value="Submit" class="btn btn-default" class="userprofilesubmit" id="userprofilesubmit" />
</form>
and this is my server.js code
app.use('/uploads', express.static(process.env.OPENSHIFT_DATA_DIR+'/uploads'));
app.use(express.limit('5mb'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/profile', function(req, res){
if(!req.session.logged_in){
res.redirect('/login');
}
console.log("dsadsa");
// Get the temporary location of the file
var tmp_path = req.files.file.path;
// Set where the file should actually exists - in this case it is in the "images" directory.
var target_path = process.env.OPENSHIFT_DATA_DIR + '/uploads/' + req.files.file.name;
// Move the file from the temporary location to the intended location
fs.rename(tmp_path, target_path, function(err) {
if (err){
throw err;
}
// Delete the temporary file, so that the explicitly set temporary upload dir does not get filled with unwanted files.
fs.unlink(tmp_path, function() {
if (err){
throw err;
}
//
console.log("reached");
res.send("uploaded");
});
});
});
Sorry about the indentations. Any help will be highly appreciated.

Node.js req.body empty

I am having a hell of a time with this one. I don't know why my node.js response is empty. It comes back {} if I send it through the javascript here, or if I use the Advanced REST client. Here is my code:
client.js
unction ajaxPost(){
var req = new XMLHttpRequest();
var payload = {'Add Item':'Add Item',
'name':document.getElementById('submitForm').elements[0].value,
'reps':document.getElementById('submitForm').elements[1].value,
'weight':document.getElementById('submitForm').elements[2].value,
'date':document.getElementById('submitForm').elements[3].value,
'lbs':document.getElementById('submitForm').elements[4].value
}
payload['test'] = 'value!';
console.log('did this happen?');
console.log(payload['test']);
var url = '/edit';
req.open('POST', url, true);
req.setRequestHeader('Content-Type', 'application/json');
req.addEventListener('load',function(){
if(req.status >= 200 && req.status < 400){
var response = JSON.parse(req.responseText);
console.log('you got a response!')
} else {
console.log("Error in network request: " + req.statusText);
}});
console.log(JSON.stringify(payload));
req.send(JSON.stringify(payload));
event.preventDefault();
}
HTML
<form id = "submitForm">
<input type="text" name="name" id="name" value='test'>Name<br>
<input type="text" name="reps" id="reps" value='10'>Reps<br>
<input type="text" name="weight" id="weight" value='100'>Weight<br>
<input type="text" name="date" id="date" value='1/1/16'>Date<br>
<input type="text" name="lbs" id="lbs" value='1'>Pounds<br>
<input type="submit" onclick = 'ajaxPost()' value="Add Item">
</form>
server
var express = require('express');
var mysql = require('./dbcon.js');
var bodyParser = require('body-parser');
var app = express();
var handlebars = require('express-handlebars').create({defaultLayout:'main2'});
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.urlencoded({ extended: false }));
app.engine('handlebars', handlebars.engine);
app.set('view engine', 'handlebars');
app.set('port', 3010);
app.post('/edit',function(req,res,next){
//var context = {};
console.log('you posted!');
console.log(req.body);
In my console, I see that the req.body is {}.
I don't know what I am doing wrong. I have tried using httpbin and I can see that the javascript works fine, which means I am probably doing something wrong on the node side, but I cannot figure out what. If I instead use method="submit" on the form, then the post goes through just fine, but it's not what I want to do. What am I doing wrong?? Because advanced REST client also fails, I am guessing it is node?
You are sending json in the request, but you only have middleware setup to handle url encoded requests. Add this to your middleware and json requests should populate in the req.body.
app.use(bodyParser.json());
More info can be found at in the body parser documentation. Specifically you'll notice that the middleware you are using urlencoded states that it only parses urlencoded bodies (this is where Content-Type is used).
You are setting the header to be json
req.setRequestHeader('Content-Type', 'application/json');
and not using bodyParser.json().
Try adding app.use(bodyParser.json());

formdata object is empty for html form post request

I'm trying to use formdata object to send form data to my server. I need this because one of my input fields is a file. However the formdata object is blank when I try to send the data to my server, it also prints out "{}". What is the issue? I have jquery updated to 11.1 which supports formdata. Thanks.
<form enctype="multipart/form-data" name="formName" id="formId">
<input type="text" name="name" class="form-control" id="name">
</form>
<button type="submit" class="btn btn-xl sub">Send Message</button>
<script>
$(".sub").click(function(){
var formElement = document.querySelector("form");
alert(formElement); //alert message is "[object HTMLFormElement]"
var d = new FormData(formElement);
alert(JSON.stringify(d)); //alert message is "{}"
$.post("/email",d,function(data){
alert("success!");
});
});
</script>
Server:
/*never reaches endpoint*/
app.post('/email', function(req, res) {
console.log("entered");
console.log(req.body) // form fields
console.log(req.files) // form files
var resume = req.files;
email(req.body, resume);
});
https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects
How are you parsing the body of POST requests on your node server?
The issue is that FormData will set the content type to be multipart/form-data, which Express' body-parser doesn't understand.
Note the comment here:
[body-parser] 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.
So in other words, you have to user a different module to handle the multipart body that FormData sends. I can recommend formidable, in which case you're server code would look something like:
const formidable = require('formidable')
exports.createPost = (req, res, next) => {
var form = new formidable.IncomingForm();
form.parse(req, (err, fields, files) => {
console.log(fields)
res.send('NOT IMPLEMENTED: pollsController createPost');
}
}

Can I use body-parser and Formidable at the same time?

I am tryint to resolve a problem a couple of days, but can't understand some things.
I have a web site created with NodeJS and ExpressJS, and for handling forms I use body-parser.
var adName = req.body.adName;
var adMessage = req.body.adMessage;
var phone = req.body.phone;
var rawPrice = req.body.price;
var rawCurrency = req.body.currency;
So, using this method I handle form values.
But now, I need to use node-formidable to parse images from users. The question is, can I use somehow
formidable only for images and body-parser for forms? Or, can anyone help me with formidable, to understand how to handle forms and attach values to my variables?
You may want to take some time out to study/practice with the formidable module. See this url: https://github.com/felixge/node-formidable
Yes, formidable can be used to process both form fields and file upload including multiple file uploads. body-parser middleware does not handle multiparts - https://github.com/expressjs/body-parser. In this case, I will advise you use formidable and drop body-parser.
See if below express app help you out.
var formidable = require('formidable'),
util = require('util'),
express = require('express'),
app = express();
app.set('port', process.env.PORT || 3600);
app.get('/', function (req, res) {
res.send(
'<form action="/upload" enctype="multipart/form-data" method="post">'+
'<input type="text" name="adName" placeholder="adName"><br>'+
'<input type="text" name="adMessage" placeholder="adMessage"><br>'+
'<input type="text" name="phone" placeholder="phone"><br>'+
'<input type="text" name="rawPrice" placeholder="rawprice"><br>'+
'<input type="text" name="rawCurrency" placeholder="rawcurrency"><br>'+
'<input type="file" name="upload" multiple="multiple"><br>'+
'<input type="submit" value="Upload">'+
'</form>'
);
});
app.post('/upload', function(req, res){
var form = new formidable.IncomingForm();
form.uploadDir = __dirname + "/data";
form.parse(req, function(err, fields, files) {
//fields is an object containing all your fields, do waht ever you want with them from here
//file is an object containing properties of your uploaded file
res.send(util.inspect({fields: fields, files: files}));
console.log('file uploaded : ' + files.upload.path + '/' + files.upload.name);
console.log('Fields : ' + fields.adName);//you can access all your fields
});
});
//starting server
app.listen(app.get('port'), function () {
console.log('Express is listening: http://localhost:%s;', app.get('port'));
});
You can use both body-parser and formidable at the same time if you wish. You can use formidable just for some specific routes and continue using body-parser on the rest. Below I show the code needed to use formidable for just one route:
const formidableMiddleware = require('express-formidable');
app.post('/api/v1/uploadfile', formidableMiddleware(), async (req, res) => {
const file = req.files.file;
console.log('file info: ' + file);
const fields = req.fields;
console.log('fields = ' + JSON.stringify(fields));
});
Take a look at this link: https://github.com/utatti/express-formidable/issues/1

Categories