ERR_EMPTY_RESPONSE error using multiparty package in Node.js - javascript

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()

Related

GET from localhost returns code 404 (Not Found)

In the file upload operation option I did with MV.Net, I get the GET http://localhost:55298/Home/test2.json 404 (Not Found) error while uploading the file. How can I fix this.
<input type="file" name="file" id="file" accept="application/JSON" />
var dosyaAdi;
$('input[type="file"]').change(function(e){
dosyaAdi = e.target.files[0].name;
$("#file").click(function () {
if ("#file".length > 1) {
$('#file').prop('disabled', true);
}
});
$.getJSON(dosyaAdi, function (data) {
$("#btn").click(function () {
const trackplayback = L.trackplayback(data, map, {
targetOptions: {
}
});
const trackplaybackControl = L.trackplaybackcontrol(trackplayback);
trackplaybackControl.addTo(map);
})
})
});
http://localhost:55298/Home/test2.json - look at the Url - your GET method is hitting the /Home/test2.json Url. As a result the system is looking for a physical file called test2.json. Not looking for an Action.
What is the name of the Action that you are trying to hit?
If it is a GET method then you can simply test the action from a web browser.
Also you had mentioned that you are trying to upload a file. Unless it is a Ajax request, you should do Http POST to upload files instead of GET.

Node.js, Express: How can I handle res.send values with the client

I'm a newbie in node.js, and I'm also using express.
I build a simple web application to upload files to a server, and save them, when they are okay. That works fine, but now I want to inform the client about the current state( is it uploaded or did it not work, because of the large size from the file).
I know that I should use res.send(), but I want to display it on the same page( with all elements on "upload.html"), where the client uploaded the file. I guess, I have to using client sided javascript to work with the sended information, but how do I communicate with server side javascript and client side javascript? Or do I not need to use client sided javascript?
(I would like to combine it later with HTML, so I can design the answer from the server with CSS.)
server.js:
var express = require('express'),
fileUpload = require('express-fileupload'),
fs = require('fs'),
obSizeOf = require('object-sizeof'),
app = express();
app.use(express.static("public"));
app.use(fileUpload());
app.get("/upload.html", function(req, res){
res.sendfile(__dirname + "/" +"upload.html");
})
app.post('/upload.html', function(req, res) {
if(obSizeOf(req.files.sampleFile) > 10000000)
{
res.send("The size of the not-uploaded file is to large! Please use a file with a maximal size of 10MB");
return;
}
else
{
var sampleFile;
if (req.files.sampleFile.name == "") {
res.send('No files were uploaded.');
return;
}
else
{
sampleFile = req.files.sampleFile;
var typ = sampleFile.mimetype.split("/");
console.log(typ[0]);
if(fs.existsSync("public/upload/image/"+typ[0]+"/"+sampleFile.name))
{
res.send("A File with the same name already exists! Please rename it!");
return;
}
else
{
sampleFile.mv('public/upload/'+typ[0]+'/'+sampleFile.name , function(err) {
if (err){
res.send('File NOT UPLOADED!');
}
else { console.log("Mieeep!"); res.send(typ[0].charAt(0).toUpperCase()+typ[0].slice(1) +' data uploaded!');
}
});
}
}
}
});
app.listen("8000");
/upload.html:
<html>
<body>
<form ref='uploadForm'
id='uploadForm'
action='/upload.html'
method='post'
encType="multipart/form-data">
Upload File
</br>
<input type="file" name="sampleFile" />
</br>
<input type='submit' value='Upload!' />
</br>
<p id="serverInformation"></p> <!--Placeholder for information from the server-->
Only images
</form>
</body>
</html>
What you actually need is socket programming. Using node js you can do that easily.
just see this link for more on socket and node js.
you can use AJAX and check the error status. there
...
<script>
$(document).ready(function() {
$("#uploadForm").submit(function() {
$.ajax({
type: "POST",
url: "/upload.html",
data: $(this).serialize(),
complete: function(xhr, statusText){
alert(xhr.status+" : "+ statusText);
}
})
})
})
</script>

How can I get a req.body from a form that is not undefined?

Whenever I submit a form with information it is returned as undefined. I have posted the code below. If I include the (enctype="multipart/form-data") in my form I dont receive anything for the body (req.body). However, if I dont include it I receive a body but the file processing does not work and the page just keeps loading.
app.post('/processupload', function(req, res) {
var date = new Date();
titles.push(req.body.pTitle);
descriptions.push(req.body.postDescription);
dates.push(date.toString());
file_names.push(req.body.fUpload);
console.log(req);
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files)
{
if(err) return res.redirect(303, '/error');
});
form.on('end', function(fields, files)
{
var temp_path = this.openedFiles[0].path;
var file_name = this.openedFiles[0].name;
var new_location = __dirname + '/public/images/';
fs.copy(temp_path, new_location + file_name);
res.redirect(303, 'home');
});
});
<form action="/processupload" enctype="multipart/form-data" method="POST" id="uploadForm" name="postForm">
<p align="center" id="pUploadForm" name="pPostForm"><label for="photoTitle">Photo Title: </label>
<input type="text" id="photoTitle" name="pTitle"><br>
<br><input type="file" id="fileUpload" name="fUpload"><br>
<br><label for="photoCaption">Photo Caption: </label><br>
<textarea rows="10" cols="50" id="photoCaption" name="postDescription"></textarea><br><br>
</p>
</form>
I created a project few weeks back that had photo upload. I used Angular and Node. But it should still work without Angular only using Node. I used multer npm package.
var AWS = require('aws-sdk');
var s3 = new AWS.S3();
var multer = require('multer');
var upload = multer({ storage: multer.memoryStorage() }); //Save photo in memory
router.post('/processupload', upload.single('photo'), function(req, res, next){
var bucketName = process.env.BUCKET_NAME;
var file = req.file;
var filename = file.originalname;
var ext = _.last(filename.split('.'))
var keyName = uuid.v4() + '.' + ext;
var url = process.env.AWS_URL + bucketName + '/' + keyName;
var params = { Bucket: bucketName, Key: keyName, Body: file.buffer, ACL: 'public-read' };
s3.putObject(params, function(err, data) {
if (err){
return res.status(400).send(err)
} else{
console.log("Successfully uploaded data to myBucket/myKey");
console.log("The URL is", url);
res.send(url)
}
});
});
This helped me uploading images then gives me back the image url from the S3 Bucket. But you can handle that file as you want. Multer allows you to access to req.file so you can do whatever you need to do, in this example I created a unique id in order to get a url to send back to the front-end and therefore use it a source somehow. This is a form working with this code:
<form action="/testupload" method='post' enctype='multipart/form-data'>
<input type="file" name="photo" id="photo" multiple=false>
<button type="submit">Submit</button>
</form>
Something important that took a long time to debug though the name="photo" in the form must be reflected by the upload.single('photo') middleware. I hope this helps, there are so many ways go around this, this is just one.
Sources:
https://www.npmjs.com/package/multer
http://docs.aws.amazon.com/AmazonS3/latest/UG/UploadingObjectsintoAmazonS3.html

Upload image without redirecting in express :(

Is there a way to use formidable without redirection to the /upload path?
As found online and in the docs..
HTML
<form action="/upload" enctype="multipart/form-data" method="post">
<input type="file" name="file">
<input type="submit" value="Upload">
</form>
EXPRESS
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
console.log(87987)
console.log(files)
console.log(files.file)
// `file` is the name of the <input> field of type `file`
var old_path = files.file.path,
file_size = files.file.size,
file_ext = files.file.name.split('.').pop(),
index = old_path.lastIndexOf('/') + 1,
file_name = old_path.substr(index),
new_path = path.join(process.env.PWD, 'public/uploads/', file_name + '.' + file_ext);
fs.readFile(old_path, function(err, data) {
fs.writeFile(new_path, data, function(err) {
fs.unlink(old_path, function(err) {
if (err) {
res.status(500);
res.json({'success': false});
} else {
res.status(200);
res.json({'success': true});
}
});
});
});
});
The image uploads into the folder but I'm redirected to the /uploads path because of the "action = '/upload'" attribute in the form element.
I would like to stay on the same page, but when I try to change the "action" value, then I'm not able to send the image to the server
use res.redirect or remove the action attribute from the form to post to the current page.
http://expressjs.com/api.html#res.redirect
if you remove the action attribute to post to the current page then you have to add a route to express for that page to process the post request
http://expressjs.com/api.html#app.route
if you have trouble with removing the action attribute then try using action="?" to post to the current page.

POST Request Issue in ExpressJS

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.

Categories