I am trying to implement file uploads with node.js and the multer middleware, but it doesn't seem to work. This is my code:
var express = require('express');
var multer = require('multer');
var done = false;
var app = express();
app.use(multer( {dest:'./uploads/',
onFileUploadStart : function(file){
console.log('File recieved:');
console.log(file);
},
onFileUploadData:function (file,data){
console.log('Data recieved');
},
onParseEnd: function(req,next){
next();
}
}));
app.use(express.static(__dirname+"/public"));
app.post('/upload',require(__dirname+'/upload.js').upload);
app.listen(3000);
My form looks like this:
<html>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name ="file">
<input type="submit" value="Upload selected file to server">
</form>
</body>
</html>
And upload.js looks like this:
exports.upload = function (req,res)
{
console.dir(req.files);
};
I think the problem is that my form is being submitted with "application/x-www-form-urlencoded" in the Content-Type header instead of "multipart/form-data", since this is what appears when I use Fiddler to monitor the request, but I have no idea why. Can anyone shed any light on this?
I got it working by adding an accept attribute to my tag in my html. I don't know why in some examples this is not used.
Here's the code for my entire form:
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name ="file" accept="application/x-zip-compressed,image/*">
<input type="submit" value="Upload selected file to server">
</form>
Check the entire project eventually: https://github.com/tutiplain/quickupload
I can see you are doing everything right. I used multer sometime back, you can look into my working implementation here. In this EJS file i have an image upload functionality and then i wrote some logic to store the file to some other location.
Make sure you have appropriate router, for example you can use router.post(..)
exports.upload= function(req,res){
// 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 = '/..provide path to store photos../' + 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;
}else{
//response logic ...
};
});
});
};
You can try this. It works for me. If any issues then let me know
var multer = require('multer');
var upload = multer({ dest: './uploads' });
router.post('/register',upload.single('profileimage'),function(req,res,next){
if (req.file) {
console.log('Uploading File');
var profileImageOriginlName=req.file.originalname;
var profileImageName=req.file.name;
var profileImageMime=req.file.mimetype;
var profileImagePath=req.file.path;
var profileImageExt=req.file.extension;
var profileImageSize=req.file.size;
}
else
{
var profileImageName='noimage.png';
}
});
Related
I am having hard time finding how i can upload an image to my image classifier api and do prediction on it.
in node js i copy paste many code examples but it only saves a copy of the file to an upload folder but there is no option to add the file to an api.
I am running both server( NodeJs and flask(api)) on my localhost.
Eg.I need something similar like AWS Rekognition makes us select an image and show the response.
This is the code that I copy pasted but don't know how add the api and send the image selected on the page
var http = require('http');
var formidable = require('formidable');
var fs = require('fs');
http.createServer(function (req, res) {
if (req.url == '/fileupload') {
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
var oldpath = files.filetoupload.path;
console.log(oldpath);
console.log('Fields', fields)
console.log('Files', files)
var newpath = 'C:/Users/Pratham Nishad/Desktop/' +
files.filetoupload.name;
fs.rename(oldpath, newpath, function (err) {
if (err) throw err;
res.write('File uploaded and moved!');
res.end();
});
});
} else {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write('<form action="fileupload" method="post"
enctype="multipart/form-data">');
res.write('<input type="file" name="filetoupload"><br>');
res.write('<input type="submit">');
res.write('</form>');
return res.end();
}
}).listen(4000);
What I want- Lets say that I have an Image Classifier ready to make classify image at XYZ.com and I want to make user select an image(PROBLEM HERE) from his/her storage and process it and post the result.
All the tutorial that i watched just selects the image from one location and paste it to destination location, no information how the image classifier running at XYZ.com will get the image.
Check out multer package on npm:
https://www.npmjs.com/package/multer
As requested I'll demonstrate how I actually used this tool.
Front-end Code:
<!DOCTYPE html>
<html>
<body>
<p>Click on the "Choose File" button to upload a file:</p>
<form action="xyz.com" method="post">
<input type="file" id="myFile" name="filename">
<input type="submit">
</form>
</body>
</html>
Backend Code:
const multer = require('multer');
//Multer DiskStorage Config
const diskStorage = multer.diskStorage({
destination: 'path/to/your/desired/folder',
filename: (req, file, call_back) => {
//Prepend date to the filename
//or anything that can uniquely identify the file
//so it won't get overwritten by the new ones
call_back(null, Date.now() + '_' + file.originalname);
}
});
//Create Multer Instance
const upload = multer({ storage: diskStorage });
//Upload picture
router.post('/uploadpic', upload.single('file'), (req, res) => {
res.status(200);
});
After the file has been saved, you can use it with the image classifier.
You are really free to create your own file structure. There are no specific constraints or rules that you have to follow.
I am new to develop Rest API, I have tried this below methods to upload a file using HTML this code works. Then I tried this in postman I got positive response but file wasn't uploaded, May I know what I have done wrong?
var express = require("express");
var app = express();
var multer = require('multer')
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now()+".jpg");
}
});
var upload = multer({ storage : storage}).single('userPhoto');
I used this below method to upload a file. It's worked when I upload a file using HTML.
But If I tried this using postman I got file is uploaded message. But in the destination folder there is no file.
app.post('/api/photo',function(req,res){
upload(req,res,function(err) {
if(err) {
// res.end({"error" : true,"message" : "Error uploading file."});
res.end("Error uploading file.");
}
res.end("File is uploaded");
// res.json({"error" : false,"message" : "File is uploaded"});
});
});
Here I have added my HTML file
<html>
<head>
<title>File upload Node.</title>
</head>
<body>
<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">
<span id = "status"></span>
</form>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.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) {
status('Error: ' + xhr.status);
},
success: function(response) {
console.log(response)
$("#status").empty().text(response);
}
});
return false;
});
});
</script>
</html>
I tried many ways but I can't find any solution, Can anyone please help me to fix this issue?
Code working good, Issue happened because of the request header.
{"Content-Type":"application/json"}
I just removed it.
This answer helped me to fix this issue
This is my server.js file
I am trying to find upload image on server. I came to know that multipart doesn't work now.
var config=require('./config');
var mongoose=require('mongoose');
var bodyparser=require('body-parser');
var express = require('express');
var morgan=require('morgan');
var nodemailer=require('nodemailer');
var fs=require('fs');
var FB=require('fb');
var app = express();
app.use(bodyparser.urlencoded({extended:true}));
//app.use(express.bodyparser({uploadDir:'./uploads'})); //This is showing error.
app.use(bodyparser.json());
app.use(morgan('dev'));
app.use('/public',express.static(__dirname + '/public'));
mongoose.connect(config.database,function(err){
if(err)
console.log(err);
else
console.log('database connected');
});
app.listen(config.port,function(err){
if(err)
console.log(err);
else
console.log('server running at '+config.port);
});
app.get('/',function(req,res){
res.sendFile(__dirname +'/public/app/views/index.html' );
});
app.post('/file-upload', function(req, res) {
// get the temporary location of the file
var tmp_path = req.files.thumbnail.path;
// set where the file should actually exists - in this case it is in the "images" directory
var target_path = './public/images/' + req.files.thumbnail.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;
res.send('File uploaded to: ' + target_path + ' - ' + req.files.thumbnail.size + ' bytes');
});
});
});
This is my form:
<form method="post" enctype="multipart/form-data" action="/file-upload">
<input type="text" name="username">
<input type="password" name="password">
<input type="file" name="thumbnail">
<input type="submit">
</form>
It is showing the following error:
TypeError: Cannot read property 'thumbnail' of undefined
How to upload the image now? I am using this for the first time. I came to know that multer is used now. But how and where to use it in my code?
The body parser middleware that you are using does not support multipart (file uploading). It only supports JSON or url encoded form submissions. I am going to point you in the direction of this stack overflow question. It talks about the same issue you are having.
SOLUTION: You need different middleware that supports multipart submission.
Im using the following code from
https://github.com/cthackers/adm-zip/wiki/ADM-ZIP-Introduction
Whant I need is to get a zip file from request(Im using express and I've request and response) and I need to extract(unzip) it to some path(in the example for my local drive) ,where should I put the req and what Im missing here to make it work
fn: function (req, res) {
var admZip = require('adm-zip');
var zip = new admZip();
zip.addLocalFile("C://TestFolder//TestZip");
in the request body im getting the zip file(im using postman and in the body I use the binary and select a zip file)
Please try my snippet code :
For some information, My App structure like this below :
my path --> C:\xampp\htdocs\service
service
|
-- tmp\
|
-- app.js
|
-- index.html
Client Side:
<html>
<body>
<h3>ZIP Upload:</h3>
<form action="/upload_zip" method="POST" enctype="multipart/form-data">
Select zip to upload:
<input type="file" name="zipFile" id="zipFile">
<input type="submit" value="Upload ZIP" name="submit">
</form>
</body>
</html>
Server Side:
Don't forget using enctype="multipart/form-data" when you post it using postman or something like that...
var express = require("express");
var fs = require("fs");
var AdmZip = require('adm-zip');
var app = express();
var multer = require("multer");
var multer_dest = multer({dest: "./tmp"}).single('zipFile');
app.get("/",function(req,res){
console.log("Show index.html");
res.sendFile(__dirname+"/"+"index.html");
});
app.post("/upload_zip",multer_dest,function(req,res){
console.log(req.file);
var zip = new AdmZip(req.file.path);
zip.extractAllTo("./tmp");
result = {
file:req.file,
message:"File has been extracted"
};
fs.unlink(req.file.path, function (e) {
if (e) throw e;
console.log('successfully deleted '+req.file.path);
});
res.end(JSON.stringify(result));
});
var server = app.listen(8081,function(){
var host = server.address().address;
var port = server.address().port;
console.log("Example App Listening at http://%s:%s",host,port);
})
Output :
You could simplify the problem by using form-data instead of binary and using multer. You can get the input file by accessing req.file after which you can perform your unzip operation.
For example, you would add to your route:
var upload = require('multer')({ dest: 'uploads/' });
var admZip = require('adm-zip');
app.post('/upload-here', upload.single('file'), function (req, res, next) {
var zip = new admZip(req.file.path);
zip.extractAllTo("C://TestFolder//TestZip", true);
});
This HTML form below is (among other things) uploading a file to a server using express.js and multer. It works fine, if a file is chosen, but not if the file is left out.
<form id="uploadform" method="post" action="/upload" enctype="multipart/form-data">
<p> Description: <input type="text" name="description"></p>
<p><input type="file" name="img"></p>
<p><input id="submit_upload" type="submit" value="Submit"></p>
</form>
My Node.js application includes the middleware multer.
var express = require('express');
var app = express();
var multer = require('multer');
app.use(multer(
{
dest: './public/img/',
rename: function (fieldname, filename) {
return filename + Date.now();
}
}));
When the form is submitted, I will be redirected to /upload, as it is defined in the HTML-Upload form with action="/upload".
In my Node.js script the form entries will be handled as shown below:
app.post('/upload', function (req, res) {
var form_description = req.body.description;
var form_datei = JSON.stringify(req.files.img.name);
form_datei = form_datei.substring(1, form_datei.length - 1);
// insert operations into database get placed here
res.redirect('/');
});
If I donĀ“t select a file in the form and submit it only with inserted text, not even the text will be submitted. Instead my console and browser window display a long error message starting as you can see below:
TypeError: Cannot read property 'name' of undefined
How can I make the form submit if no file is selected?
The file upload should be optional.
Thanks for your help!
The problem is when you try to retrieve the image name in req.files.img.name. Since req.files.img will return undefined, you can't read the property there.
Check if a file was submitted before trying to use it:
app.post('/upload', function (req, res) {
var form_description = req.body.description;
if(req.files.img) {
var form_datei = JSON.stringify(req.files.img.name);
form_datei = form_datei.substring(1, form_datei.length - 1);
// insert operations into database get placed here
}
res.redirect('/');
});