Uploading an image in express just hangs - javascript

html:
<form method='post' action='upload_bg' enctype="multipart/form-data">
<input type='file' name='fileUploaded'>
<input type='submit'>
My index.js
app.route('/upload_bg')
.post(function (req, res) {
var fstream;
req.busboy.on('file', function (fieldname, file, filename) {
console.log(filename);
fstream = fs.createWriteStream(__dirname + '/imgs/' + "latest_upload.jpg");
file.pipe(fstream);
fstream.on('close', function () {
res.redirect('back');
});
});
});
My variables:
var express = require('express');
var busboy = require('connect-busboy');
var path = require('path');
var fs = require('fs-extra');
So the user clicks the button, selects an image, and selects submit. This hit's my route upload_bg. I've had it working before, and I changed a few things around but I'm unable to understand why it isn't working. I look in the network tab and the request is just pending indefinitely.

Here is my simple solution using express-fileupload module:
First intall express fileupload module using following command:
npm install express-fileupload
HTML page code:
<html>
<body>
<form ref='uploadForm'
id='uploadForm'
action='http://localhost:3000/upload_bg'
method='post'
encType="multipart/form-data">
<input type="file" name="sampleFile" />
<input type='submit' value='Upload!' />
</form>
</body>
</html>
node server code:
server.js:
var express=require('express');
var app = express();
var fileUpload = require('express-fileupload');
// default options
app.use(fileUpload());
app.post('/upload_bg', function(req, res) {
if (!req.files)
return res.status(400).send('No files were uploaded.');
// The name of the input field (i.e. "sampleFile") is used to retrieve the uploaded file
let sampleFile = req.files.sampleFile;
// Use the mv() method to place the file somewhere on your server
// Make sure 'imgs' folder is already created inside current directory otherwise it will throw error where this server.js file is placed
sampleFile.mv(__dirname + '/imgs/latest_upload.jpg', function(err) {
if (err)
return res.status(500).send(err);
res.send('File uploaded!');
});
});
app.listen(3000,function(){
console.log("App listening on port 3000")
});
Hope this will help. For complete code refer https://github.com/richardgirges/express-fileupload

I would personally re-style your code a little bit. And I would use ajax. Here is some example code:
index html:
<button class="btn btn-lg upload-btn" type="button">Upload image</button>
<input id="upload-input" type="file" name="uploads[]" multiple="multiple">
client js:
This can/should be inside of index.html
$('.upload-btn').on('click', function (){
$('#upload-input').click();
$('.progress-bar').text('0%');
$('.progress-bar').width('0%');
});
$('#upload-input').on('change', function(){
var files = $(this).get(0).files;
if (files.length > 0){
// create a FormData object which will be sent as the data payload in the
// AJAX request
var formData = new FormData();
// loop through all the selected files and add them to the formData object
for (var i = 0; i < files.length; i++) {
var file = files[i];
// add the files to formData object for the data payload
formData.append('uploads[]', file, file.name);
}
$.ajax({
url: '/upload',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(data){
console.log('upload successful!\n' + data);
},
});
}
});
server js:
var express = require('express');
var app = express();
var path = require('path');
var formidable = require('formidable');
var fs = require('fs');
var l;
//... other code here
app.get('/upload', function(req, res){
res.sendFile(path.join(__dirname, 'index.html'));
});
app.post('/upload', function(req, res){
var form = new formidable.IncomingForm();
form.multiples = true;
form.uploadDir = path.join(__dirname, '/uploads');
form.on('file', function(field, file) {
fs.readdir('uploads/', function(err, items) {
console.log(items.length);
l = items.length
console.log(l);
fs.rename(file.path, "uploads/"+l+".jpg", function(err) {
if ( err ) console.log('ERROR: ' + err);
});
});
});
form.on('error', function(err) {
console.log('An error has occured: \n' + err);
});
form.on('end', function() {
res.end('success');
});
form.parse(req);
});
Hope this helps!

Related

nodejs res.download() file

i'm pretty new to nodejs and stuff, and i;ve been researching on how to upload and download a file from a nodejs server
the upload part works just fine, the problem is the download part
the code i wrote has no errors but however, the file itself is not downloading, i have no idea where i went wrong
here's my uploadss.js file
var express = require('express');
var multer = require('multer');
var path = require('path');
var fs = require('fs');
var app = express();
var router = express.Router();
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, __dirname + '/uploads');
},
filename: function (req, file, callback) {
callback(null, Date.now() + path.extname(file.originalname));
}
});
var upload = multer({ storage : storage }).array('userPhoto',5);
app.set('views', __dirname + '/views');
app.get('/index', function(req, res){
res.render('indexss.ejs');
});
app.use('/', router);
app.post('/api/photo', function(req, res){
upload(req, res, function(err) {
if(err) {
return res.end("Error uploading file.");
}
res.end("File is uploaded");
});
});
router.get('/download', function(req, res) {
var dir = path.resolve(".") + '/uploads/';
fs.readdir(dir, function(err, list) {
if (err)
return res.json(err);
else
res.json(list);
});
});
router.get('/download/:file(*)', function(req, res, next){
var file = req.params.file;
var path = require('path');
var path = path.resolve(".") + '/uploads/' + file;
res.download(path, file, function(err){
if (err){
console.log(err);
} else {
console.log('downloading successful');
}
});
});
app.listen(8080);
and here's the indexss.ejs file that contains the html and javascript
<html>
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" ></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery.form/3.51/jquery.form.min.js"></script>
<script>
$(document).ready(function() {
$('#uploadForm').submit(function() {
$("#status").empty().text("File is uploading...");
$(this).ajaxSubmit({
error: function(xhr) {
console.log(xhr);
status('Error: ' + xhr.status);
},
success: function(response) {
$("#status").empty().text(response);
console.log(response)
}
});
return false;
});
$.ajax({
url: "/download",
method: "get",
success: function(data){
downloadArray = data;
for (i = 0; i < downloadArray.length; i++){
console.log(downloadArray[i]);
console.log(typeof downloadArray[i]);
$('#downloadList').append("<a href='#' onclick='downloadFile(this)'>" + downloadArray[i] + "</a><br>");
}
}
});
});
function downloadFile(selectedFile){
fileToDownload = $(selectedFile).text();
console.log(fileToDownload);
$.ajax({
url: "/download/" + fileToDownload,
method: "get",
success: function(){
console.log('successful downloading');
}
});
}
</script>
</head>
<body>
<form id="uploadForm"
enctype="multipart/form-data"
action="/api/photo"
method="post">
<input type="file" name="userPhoto" multiple />
<input type="submit" value="Upload" name="submit">
<input type='text' id='random' name='random'><br>
<span id = "status"></span>
</form>
<div id='downloadList'></div>
</body>
You're overriding path with filename parameter. Try this:
res.download(path);
And read res.download(path [, filename] [, fn]) at: https://expressjs.com/en/api.html
try the following code
server
var app = express();
var fs = require('fs');
app.get('/image', function (req, res) {
var path_image = req.headers.path;
var src = fs.createReadStream(path_image);
src.on('open', function () {
src.pipe(res);
log.info('down completed: ' + path_image);
});
src.on('error', function (err) {
log.error('' + err);
});
});
path_image is your file path, i use the client-side information sent
java-client use library https://github.com/koush/ion
Ion.with(MainActivity.this)
.load("http://IP:PORT/image")
.setHeader("path", path_image_on_server)
.progress(new ProgressCallback() {
#Override
public void onProgress(long downloaded, long total) {
Log.e("bc", "" + downloaded + " / " + total);
}
})
.write(new File(path_image_save_file))
.setCallback(new FutureCallback<File>() {
#Override
public void onCompleted(Exception e, File file) {
if (e != null) {
Log.e("bc", e.toString());
}
if (file != null) {
Log.e("bc", file.getAbsolutePath());
}
}
});

I am trying to receive video file and save it on the server with multer

I am trying to receive a video file and save it in the uploads folder with the right extensions using node, express, and multer. I know my video is getting passed to the server correctly but it isn't saving how I would like it. This is my backend code.
var express = require("express");
var bodyParser = require("body-parser");
var multer = require("multer");
var app = express();
var path = require('path');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// this is cors this allows my angular app to call this node backend even though they are both on local host
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
// here I am calling multer to get the filename of the file I am serving up specifying what folder I want it to go in
var storage = multer.diskStorage({
destination: function (request, file, callback){
callback(null, './uploads');
},
filename: function(request, file, callback){
console.log(file);
callback(null, file.originalname)
}
});
var upload = multer({storage: storage});
// this app.post calls the post method this is where I will upload the file
app.post('/upload', function (request, response) {
upload(request, response, function(err) {
if(err) {
console.log('Error Occured');
return;
}
console.log(request.file);
response.end('Your file Uploaded');
console.log('Video Uploaded');
})
});
// my app is listening on localhost port 8080 for the post to be called
var server = app.listen(8080, function () {
console.log('Listening on port ' + server.address().port)
});
this is my error
c:\toolbox\pos-estate-data\oneops\ScoSopBackend>node app.js
Listening on port 8080
TypeError: upload is not a function
at c:\toolbox\pos-estate-data\oneops\ScoSopBackend\app.js:29:6
at Layer.handle [as handle_request] (c:\toolbox\pos-estate-data\oneops\ScoSo
pBackend\node_modules\express\lib\router\layer.js:95:5)
at next (c:\toolbox\pos-estate-data\oneops\ScoSopBackend\node_modules\expres
s\lib\router\route.js:131:13)
client side code
upLoad() {
let strSopName : string = (<HTMLInputElement>document.getElementById("sopName")).value;
if(strSopName == "" || strSopName == null || strSopName == "Error you must enter a sop name"){
strSopName = "Error you must enter a sop name"
return;
}
this.makeFileRequest("http://localhost:8080/upload", [], this.filesToUpload).then((result) => {
console.log(result);
}, (error) => {
console.error(error);
});
}
makeFileRequest(url: string, params: Array<string>, files: Array<File>){
return new Promise((resolve, reject) => {
var formData: any = new FormData();
var xhr = new XMLHttpRequest();
for(var i = 0; i < files.length; i++){
formData.append("uploads[]", files[i], files[i].name);
}
xhr.onreadystatechange = function() {
if(xhr.readyState == 4){
if(xhr.status == 200){
resolve(JSON.parse(xhr.response));
}else {
reject(xhr.response);
}
}
}
xhr.open("POST", url, true);
xhr.send(formData);
})
}
html
<br>
<input type="file" (change)="fileChangeEvent($event)" name="videofile" placeholder="upload file..." class="form-control" id="Video" accept="video/mp4, video/x-m4v, video/*" required>
<br>
You aren't properly initialising multer's upload middleware. That's why experiencing type error.
In your case, you want to upload single file, try the following initialisation and replace 'file' with input name related to file in form
e.g.,
You have input tag of type="file" with name="videoFile" in form in your html
<form method="post" action="/upload" enctype="multipart/form-data">
<input type="file" name="videoFile"><br>
<input type="submit" value="Submit">
</form>
Then, you can initialise multer to pull file
var upload = multer({storage: storage}).single('videoFile');
Please note that it is name of input tag that receives file, not filename itself.
EDIT
As discussed in comments, you are uploading multiple files.
Try
var upload = multer({storage: storage}).array('uploads');
Hope it helps you.

Sending an image to Node.js server from client (AngularJS)

I have a really quick question:
I have an img tag (in my template file) that holds an image and in my Angular Controller I call:
var image = document.getElementById('srcImage');
I want to send this image ^ to the backend (I am using REST). The url I would use for this POST method is:
'/api/v1/images/addImage'
I've tried ng-file-upload and $http.post, but nothing seems to be working. Is there any way that I can simply send this image over to the server so I can store it in a database or file system? I am open to any solutions to making this happen.
Thanks!!
You can use below libraries, they have good documentation also
For Frontend -
https://github.com/nervgh/angular-file-upload
For Backend -
https://github.com/expressjs/multer
Sample Snippet -
In HTML :
<input type="file" nv-file-select="" uploader="ctrl.uploader" multiple />
Angular Controller :
vm.uploader = new FileUploader({
url: 'http://' + SERVER_URL + '/upload',
formData: [{
id: 1
}]
});
vm.save = function() {
vm.uploader.onBeforeUploadItem = function (item) {
console.log(item);
/* some action */
};
vm.uploader.onSuccessItem = function (item, imgResponse, status, headers) {
console.log(item);
console.log(imgResponse);
console.log(status);
console.log(headers);
/* some action */
};
};
Node Server :
var fs = require('fs');
var multer = require('multer');
var fileName = '';
var storage = multer.diskStorage({
destination: function (req, file, cb) {
var dirPath = 'path/to/save/file'
if (!fs.existsSync(dirPath)) {
var dir = fs.mkdirSync(dirPath);
}
cb(null, dirPath + '/');
},
filename: function (req, file, cb) {
var ext = file.originalname.substring(file.originalname.lastIndexOf("."));
fileName = Date.now() + ext;
cb(null, fileName);
}
});
// Assuming Express -
app.get('/upload', function (req, res) {
var upload = multer({
storage: storage
}).array('file', 12);
upload(req, res, function (err) {
if (err) {
// An error occurred when uploading
res.json(err);
}
res.json(fileName);
});
});
You can try multipart/form-data like this:
<form id = "uploadForm"
enctype = "multipart/form-data"
action = "/api/photo"
method = "post"
>
<input type="file" name="userPhoto" />
<input type="submit" value="Upload Image" name="submit">
</form>

Files undefined using multiparty

I want to upload img using node.js , i am using express and multiparty , my code looks like
html
<!DOCTYPE html>
<html>
<body>
<form method="post" action="/img">
Select image to upload:
<input type="file" name="fileToUpload" id="fileToUpload">
<input type="submit" value="Upload Image" name="submit">
</form>
</body>
</html>
js
var express = require("express");
var app=express();
var http=require("http").Server(app);
app.get("/",function(req,res){
res.end("hello")
});
app.get("/upload",function(req,res){
res.sendFile(__dirname + "/form.html")
})
app.post("/img",function(req,res){
var multiparty = require("multiparty");
var form = new multiparty.Form();
form.parse(req,function(err,fields,files){
var img = files.images[0];
console.log(img)
})
})
http.listen(3000,function(){
console.log("listening on 3000")
})
When i upload something , it throws error
Cannot read property images of undefined
Being new to back end i have no idea why its happening , the directory img exists in folder where html and js are located.
Add enctype to form:
<form method="post" action="/img" enctype="multipart/form-data">
PS: For upload image, I suggest you use formidable, somelike this.
you can use multer for uploading files, see the code below, For front end:
<html>
<head>
<title>FileUpload</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
<form id = "uploadForm"
enctype = "multipart/form-data"
action = "http://localhost:3000/api/photo"
method = "post"
>
<input type="file" name="userPhoto" multiple />
<input type="submit" value="Upload Image" name="submit" id="btnUpload">
<span id="spnStatus" />
</form>
<script>
$(document).ready(function(){
$('#btnUpload').click(function(){
$('#spnStatus').empty().text("File is Uploading");
$(this).ajaxSubmit({
error : function(xhr){
status('Error : '+xhr.status);
}
success : function(response){
$('#spnStatus').empty().text(xhr);
}
});
});
});
</script>
</body>
</html>
NodeJS :
var express = require("express");
var multer = require("multer");
var bodyParser = require("body-parser");
var app = express();
app.use(bodyParser.json());
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
}
});
var upload = multer({ storage : storage }).array('userPhoto',1);
app.get('/',function(req,res){
res.sendFile(__dirname + "/fileUpload.html");
});
app.post('/api/photo',function(req,res){
upload(req,res,function(err) {
if(err) {
return res.end("Error uploading file.");
}
res.end("File is uploaded");
});
});
app.listen(3000,function(){
console.log("Working on port 3000");
});
and you can upload multiple files at same time if you want, for example increase the userPhoto to 5 var upload = multer({ storage : storage }).array('userPhoto',5);

Upload files with node.js

I have this code in order to upload files with node.js:
app.use(express.bodyParser());
// or, as `req.files` is only provided by the multipart middleware, you could
// add just that if you're not concerned with parsing non-multipart uploads,
// like:
app.use(express.multipart());
app.get('/',function(req,res){
fs.readFile('uploadHTML.html',function (err, data){
res.writeHead(200, {'Content-Type': 'text/html','Content-Length':data.length});
res.write(data);
res.end();
});
});
app.post('/upload',function(req,res)
{
console.log(req.files);
fs.readFile(req.files.displayImage.path, function (err, data) {
// ...
var newPath = __dirname;
fs.writeFile(newPath, data, function (err) {
res.redirect("back");
});
});
});
Here is the HTML file:
<html>
<head>
<title>Upload Example</title>
</head>
<body>
<form id="uploadForm"
enctype="multipart/form-data"
action="/upload"
method="post">
<input type="file" id="userPhotoInput" name="displayImage" />
<input type="submit" value="Submit">
</form>
<span id="status" />
<img id="uploadedImage" />
</body>
</html>
When I upload the file, it gives me the next error:
TypeError: Cannot read property 'displayImage' of undefined at c:\NodeInstall\nodejs\express.js:42:22 at callbacks (c:\NodeInstall\nodejs\node_modules\express\lib\router\index.js:164:37) at param (c:\NodeInstall\nodejs\node_modules\express\lib\router\index.js:138:11) at pass (c:\NodeInstall\nodejs\node_modules\express\lib\router\index.js:145:5) at Router._dispatch (c:\NodeInstall\nodejs\node_modules\express\lib\router\index.js:173:5) at Object.router (c:\NodeInstall\nodejs\node_modules\express\lib\router\index.js:33:10) at next (c:\NodeInstall\nodejs\node_modules\express\node_modules\connect\lib\proto.js:193:15) at Object.expressInit [as handle] (c:\NodeInstall\nodejs\node_modules\express\lib\middleware.js:30:5) at next (c:\NodeInstall\nodejs\node_modules\express\node_modules\connect\lib\proto.js:193:15) at Object.query [as handle] (c:\NodeInstall\nodejs\node_modules\express\node_modules\connect\lib\middleware\query.js:45:5)
What could be the reason?
I do recommend you to use awesome module https://github.com/domharrington/fileupload for handling file uploads in node/express.
var fileupload = require('fileupload').createFileUpload('/uploadDir').middleware
app.post('/upload', fileupload, function(req, res) {
// files are now in the req.body object along with other form fields
// files also get moved to the uploadDir specified
})
Another way to upload files could be using something like this
Jade template
form.data(action='/user/register', method='post', class="long-fields", enctype='multipart/form-data')
input(type="text" name="name")
input(name='fileLogo', type='file')
input(type="submit" value="Register")
Controller
formidable = require('formidable'); //file upload handling via form
uuid = require('node-uuid'); //Unique ID
path = require('path'); //Path compiler
fs = require('fs'); //FileSystem
var form = new formidable.IncomingForm();
form.keepExtensions = false;
form.maxFieldsSize = 2 * 1024 * 1024; //2mb
form.parse(req, function(err, fields, files) {
console.log(fields);
console.log(files);
fs.readFile(files.fileLogo.path, function (err, data) {
var pathNew = __dirname + '/../../uploads/' + uuid.v1() + path.extname(files.fileLogo.name)
fs.writeFile(pathNew, data, function (err) {
console.log('uploaded', pathNew);
});
});
res.send(jade.renderFile( settings.pathLess + prefix + '/register.jade', {
req : req
}));
});

Categories

Resources