File not uploaded using node js multer - node.js

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

Related

Uploading file with express-fileupload

I am trying to upload a file with express-fileupload and am having no luck getting it to work. I can get the file (in this case an image) to 'upload' in the sense that I can get the console to show an image uploaded with the correct folder.
startup.js
router.get('/upload', function(req, res) {
res.render('upload');
});
router.post('/upload', function(req, res) {
// The name of the input field (i.e. "sampleFile") is used to retrieve the uploaded file
let startup_image = req.files.image;
// Use the mv() method to place the file somewhere on your server
startup_image.mv('/images' , function(err) {
if (err) {
console.log(err);
}
});
});
Then my html form is
<form ref='uploadForm'
id='uploadForm'
action='/upload'
method='post'
encType="multipart/form-data">
<input type="file" name="image" />
<input type='submit' value='Upload!' />
</form>
You are pointing the directory where the file would go to, but you are not giving it a file name. I would say let the user decide the file name for the client side and add it to the path.
<input name="userFileName" type="text">//userFilename Here</input>
var myFILENAME = req.body.userFilename
startup_image.mv('/images/'+myFILENAME+'.jpg', ..) //myFILENAME needs to be added here
Also please see Full Example in how to upload files with express-fileupload
UPDATE
I found solution to your problem you need to add __dirname to this line which will let the program know your current directory to your source code.
startup_image.mv(__dirname + '/images' , function(err) {..
UPDATE 2
Here is my source code, if you want you can try it with this.
my html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form ref='uploadForm' encType="multipart/form-data" class="" action="/upload" method="post">
<input type="text" name="fileName" value=""><br>
<input type="file" name="foo" value=""><br>
<input type="submit" name="" value="upload!">
</form>
</body>
</html>
my main source
var express = require("express);
var app = express();
const fileUpload = require('express-fileupload');
//npm install ejs, express, express-fileupload
//middleware
app.use(express.static(__dirname));
app.set('view engine', 'ejs');
app.use(fileUpload());
app.get('/inputFile', function(req, res){
res.render('inputt');
});
app.post('/upload', function(req, res) {
// The name of the input field (i.e. "sampleFile") is used to retrieve the uploaded file
var startup_image = req.files.foo;
var fileName = req.body.fileName;
// Use the mv() method to place the file somewhere on your server
startup_image.mv(__dirname + '/images/' + fileName + '.jpg' , function(err) {
if(err){
console.log(err);
}else{
console.log("uploaded");
}
});
});
app.listen(7777);
using async/await style
in your server file do this
const fileUpload = require('express-fileupload');
app.use(
fileUpload({
limits: { fileSize: 50 * 1024 * 1024 },
useTempFiles: true,
// dir for windows PC
tempFileDir: path.join(__dirname, './tmp'),
}),
);
then in your controllers, do this
const file = req.files.filename;
await file.mv(file.name);
if (!file || Object.keys(req.files).length === 0) {
return res.status(400).console.error('No files were uploaded.');
}
This solution is for non ejs and exporting modules solution:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>File Upload</title>
</head>
<body>
<form ref='uploadForm' encType="multipart/form-data" class="" action="/path/to/nodejs/upload/file" method="post">
<input type="file" name="my_file"><br>
<input type="submit" name="" value="upload">
</form>
</body>
</html>
Now here is the NodeJS
const express = require("express");
const app = express();
const fileUpload = require('express-fileupload');
app.use(fileUpload({ safeFileNames: true, preserveExtension: true }))
app.post('/', function(req, res) {
// The name of the input field (i.e. "sampleFile") is used to retrieve the uploaded file
let the_file = req.files.my_file;
the_file.mv('/path/to/html/uploads/up/' + the_file.name , function(err) {
res.writeHead(200, {"Content-Type": "text/plain"});
if(err){
console.log(err);
res.write(err);
res.end();
} else {
console.log("uploaded");
res.write("upload of file "+the_file.name+" complete");
res.end();
}
});
});
module.exports = app;
You have to create folder images!
//install path module
const path = require('path');
// remaining code
let startup_image = req.files.image;
startup_image.mv(path.resolve(__dirname,'/images',startup_image.name), function(error){
//remaining code
})
this way
file.mv(path.resolve(__dirname, '../public/images', filename)

zero byte file is created in s3 while trying to resize and upload using multer in nodejs?

Below is my app.js file.. Whenever i make an attempt to resize and upload my image using multer-imager module a zero byte file is getting created everytime and i am not getting any response (keeps loading on post action).
/*********app.js*********/
var express = require('express'),
aws = require('aws-sdk'),
bodyParser = require('body-parser'),
multer = require('multer'),
imager = require('multer-imager'),
multerS3 = require('multer-s3');
gm = require('gm');
var Upload = require('s3-uploader');
var app = express(),
s3 = new aws.S3();
app.use(bodyParser.json());
var upload = multer({
storage: imager({
dirname: 'directory',
bucket: 'bucket',
accessKeyId: 'accessKeyId',
secretAccessKey: 'my secretAccessKey',
region: 'my region',
filename: function (req, file, cb) { // [Optional]: define filename (default: random)
cb(null, Date.now()) // i.e. with a timestamp
}, //
gm: { // [Optional]: define graphicsmagick options
width: 200, // doc: http://aheckmann.github.io/gm/docs.html#resize
height: 200,
options: '!',
format: 'png' // Default: jpg
},
s3 : { // [Optional]: define s3 options
Metadata: { // http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html
'customkey': 'data' // "x-amz-meta-customkey","value":"data"
}
}
})
});
app.post('/upload', upload.any(), function(req, res, next){
console.log(req.files); // Print upload details
res.send('Successfully uploaded!');
});
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');
});
app.listen(3001, function () {
console.log('Example app listening on port 3001!');
});
The below is my index.html file.
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
Hey! Lets try uploading to s3 directly :)
<form method="post" enctype="multipart/form-data" action="/upload">
<p>
<input type="text" name="title" placeholder="optional title"/>
</p>
<p>
<input type="file" name="upl"/>
<!-- <input type="file" name="uplo"/> -->
</p>
<p>
<input type="submit"/>
</p>
</form>
</body>
</html>
but i can able up upload an image without doing anykind of modification using multer-s3 module.But resizing is mandatory for me.Help me to get rectify these error.
I think GraphicsMagick package not installed in your system(Not NPM package).
Please go through GraphicsMagick guide and install GraphicsMagick in your system
http://www.graphicsmagick.org/README.html

MULTER: How to let user upload a photo and add additional information (e.g. name) to post request

I have a basic multer app working here:
https://github.com/EngineeredTruth/multer
Here's the HTML
<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" multiple />
<input type="submit" value="Upload Image" name="submit">
<select name="carlist" form="carform">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
<input type="text" value="title" name="title">
</br><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>
Here's the Node/Express server
var express = require("express");
var bodyParser = require("body-parser");
var multer = require('multer');
var app = express();
app.use(bodyParser.json());
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads');
},
filename: function (req, file, callback) {
if( file.mimetype === 'image/jpeg'){
var name = Date.now() + "." + 'jpg'
} else if (file.mimetype === 'image/png'){
var name = Date.now() + "." + 'png'
}
callback(null, name);
}
});
var limits = {
fileSize: 10000000
}
var upload = multer({ storage : storage, limits : limits }).array('userPhoto',10)
// console.log(upload());
app.get('/',function(req,res){
res.sendFile(__dirname + "/index.html");
});
app.post('/api/photo', function(req,res){
// console.log('post request: ',req);
upload(req,res,function(err) {
console.log('after upload');
//console.log(req.body);
//console.log(req.files);
if(err) {
return res.end("Error uploading file: ", err);
}
res.end("File is uploaded");
});
});
app.listen(3000,function(){
console.log("Working on port 3000");
});
Everything works and the user can upload a picture. However, I want the user to be able to title the photo and also select the type of car is in the picture by selecting one of the cars from the select (dropdown) menu.
I can't seem to find a way to access 'carlist' and 'title' from my node server where the post request is received. When I console.log 'req', I don't see carlist or title anywhere. Is there a way I can get this information to my node server from the form post action?
Taken from: https://github.com/expressjs/multer/issues/381
if your file input element is in the top of form then every data below
that gets assigned to req.body after your image is uploaded, in the
result of which body remains empty while you upload photo.. So take
file input element to very bottom of your form so that req.body will
have data from other input elements
So basically have the file input at the bottom of the form. Also req.body doesn't appear in the '/api/photo' section, but suddenly appears in the 'destination and 'filename' middleware, which is inside the upload function

Upload image to html

i'm trying to upload my image and saves it automatically to my database (mongodb). But i'm stuck with uploading the image. Here's my server.js:
var express = require("express");
var multer = require('multer');
var app = express();
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}).single('userPhoto');
app.get('/',function(req,res){
res.sendFile(__dirname + "/index.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 here's my index.html:
<!DOCTYPE html>
<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 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) {
$("#status").empty().text(response);
console.log(response);
}
});
//Very important line, it disable the page refresh.
return false;
});
});
</script>
</html>
I got this error when i try to run it
POST http://localhost:8051/api/photo 404 ()
send # jquery.min.js:4
ajax # jquery.min.js:4
o # jquery.form.min.js:1
e.fn.ajaxSubmit # jquery.form.min.js:1
(anonymous function) # (index):25
dispatch # jquery.min.js:3
i # jquery.min.js:3
(index):28
Uncaught TypeError: status is not a function(…)
error # (index):28
t.error # jquery.form.min.js:1
n # jquery.min.js:2
fireWith # jquery.min.js:2
w # jquery.min.js:4
d # jquery.min.js:4
My question is, how do i fix the error and how do i save the image to mongodb? Thankyou.
You're getting an error on line 28:
status('Error: ' + xhr.status);
You probably want to change that line to:
$("#status").empty().text('Error: ' + xhr.status);
That won't fix your problem, but it should show the upload error you're getting so you can take the next step. Good luck!

node.js upload with multer not working

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';
}
});

Resources