I'm struggling uploading an image to a local folder using Node and Multer.
The response i get it's successfully, but the image don't save in the folder.
I have already lost a week trying to fix it
And yes, i have checked the destination route, in case you wonder.
This is my frontend:
<form id="tasasImage" enctype="multipart/form-data" style="display: flex; flex-direction: column;">
<input type="file" name="photo" id="photo" class="file"> <br>
<div id="uploadImg" class="btn btn-primary">ENVIAR</div>
</form>
<script>
$("#uploadImg").click(function () {
if ($('#photo').val().length > 0) {
var formData = new FormData($('#tasasImage')[0]);
console.log([...formData])
$.ajax({
url: "",
data: formData,
type: "POST",
processData: false,
contentType: false,
success: function(r){
console.log('Uploaded successfully');
$("#photo").val('');
},
error: function (e) {
console.log("some error", e);
}
});
}
</script>
And the backend:
var storageTasas = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, config.urlBase+'public/images/tasas');
},
filename: function(req, file, callback) {
var name = now+'-'+file.originalname;
callback(null, name);
}
})
var uploadTasas = multer({ storage: storageTasas }).single('photo');
const tasasUploadImage = (req, res) => {
uploadTasas(req, res, (err) => {
if (err) { console.error(err); }
else {console.log('Ssuccessfully Uploaded') };
})
res.send({'file': now});
}
router.post('/admin/aliados/tasas/:id', adminController.tasasUploadImage);
The url you are passing empty in the JQuery / Client script, it should be url : /admin/aliados/tasas/1234
The form data should be like this
var formData = new FormData($('#tasasImage'));
simple multipart file upload with express.js and multer with ajax
Related
could you please tell me how to upload the file on some directory current example (uploads folder) .Here is my server side code
app.post('/upload', function (req, res) {
console.log('abcc')
upload(req, res, function (err) {
if (err) {
res.json({error_code: 1, err_desc: err});
return;
}
res.json({error_code: 0, err_desc: null});
});
});
full code node js
https://repl.it/repls/LustrousCharmingCommunication
I used this server and hit the service using client and upload only attached file
here is my request client code
https://jsbin.com/luwezirive/edit?html,js,output
$(function () {
$('.submit').on('click', function (e) {
e.preventDefault();
e.stopPropagation();
if ($('#fileId').val().length === 0) {
alert('please insert file')
} else {
var form = $('#fileUploadForm')[0];
// Create an FormData object
var data = new FormData(form);
console.log('fffff')
$.ajax({
url: 'https://lustrouscharmingcommunication--five-nine.repl.co/upload',
type: 'POST',
data: data,
cache: false,
enctype: 'multipart/form-data',
dataType: 'json',
processData: false, // Don't process the files
contentType: false, // Set content type to false as jQuery will tell the server its a query string request
success: function (data, textStatus, jqXHR) {
console.log('succsss');
if (typeof data.error === 'undefined') {
// Success so call function to process the form
}
else {
// Handle errors here
console.log('ERRORS: ' + data.error);
}
},
error: function (jqXHR, textStatus, errorThrown) {
// Handle errors here
console.log('ERRORS: ' + textStatus);
// STOP LOADING SPINNER
}
});
}
})
})
I am getting success but file is not uploaded why ?
upload method
var storage = multer.diskStorage({ //multers disk storage settings
destination: function (req, file, cb) {
cb(null, './uploads/')
},
filename: function (req, file, cb) {
var datetimestamp = Date.now();
cb(null, file.fieldname + '-' + datetimestamp + '.' + file.originalname.split('.')[file.originalname.split('.').length - 1])
}
});
var upload = multer({ //multer settings
storage: storage
}).single('file');
any update ?
The simplest way is using multer. https://github.com/expressjs/multer
Example taken from the documentation:
var express = require('express')
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })
var app = express()
app.post('/profile', upload.single('avatar'), function (req, res, next) {
// req.file is the `avatar` file
// req.body will hold the text fields, if there were any
})
I'm making a web app that allows users to upload and search for a recipe. A user can upload a recipe by filling a form and press a button to perform a POST request. I managed to save the recipe object, but I can't assign an image to it. I tried to use Multer, but I get "underfined" when I do log(req.file). I followed YouTube tutorials which only had app.js and index.ejs and it works, so I don't know if it's my Ajax code causing the issue??!!.
I have main.handlebars and main.css, and I have a folder called uploads but still always get undefined in the terminal, below is part of my code:
THANKS!!
upload.handlebars:
<label for="Userphrase">Recipe Name:</label>
<input type = "text" name = "recipeName" id = "recipeName"><br>
<label>Upload an image:</label>
<div class="container">
<input name="myImage" type="file"<br>
</div>
.
.
.
<script type = "text/javascript" src = "/public/palindrome.js"></script>
Ajax, only the request is here since i do error checking before that:
$("form").submit(function(e){
$.ajax({
type: "POST",
url: "/upload",
data: obj,
success: function(data){
alert("recipe added successfully!");
},
dataType: "json"
});
}
index.js:
at the top i have:
const storage = multer.diskStorage({
destination: './public/uploads/',
filename: function(req, file, cb){
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
}
});
const upload = multer ({
storage: storage
}).single('myImage');
then inside the POST route i have:
router.post('/upload',(req,res)=>{
upload(req, res, (err) => {
if(err){
res.render('index',{
msg: err
});
}else{
console.log(req.file);
res.send('test');
}
});
You have to send image in form data like
var formData = new FormData();
formData.append('imageName', imageFile);
on node side user same name('imageName') for multer it will get image from it
for more to multer check
https://www.npmjs.com/package/multer
For simplicity's sake, just use HTML form with enctype set to multipart/form-data on the client side. On the server side, say you're using Node.js, the uploaded files can be found in the request provided you're using the multer middleware to parse the form data. That's it.
You need to append that file to formData and then send it to server
Javascript:
var formData = new FormData();
jQuery.each(jQuery('#fileUpload')[0].files, function (i, file) {
formData.append('file', file);
});
$.ajax({
type: 'POST',
url: //To your route eg: /saveImage,
data: formData,
contentType: false,
processData: false,
success: function (result) {
if (result.status != 0) {
console.log(result.message)
return;
}
console.log(result.message)
}
});
Now at your route use multer
Node
var multer = require('multer')
var path = require("path");
// Check for extension of image
const getExtension = file =>{
if (file.mimetype == "image/jpeg")
ext = ".jpeg"
else
ext =".png"
return ext;
}
//initialize multer
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, path.join(__dirname, '../public/images'))
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() + getExtension(file))
}
})
var upload = multer({storage:storage})
router.post('/saveImage', upload.single('file'), (req, res, next)=>{
if (req.file && req.file.mimetype != 'image/jpeg' && req.file.mimetype != 'image/png')
return res.json({
status:1,
message:"Please Choose JPG or PNG images"
})
if(req.file){
let iamge = "/images/" + req.file.filename
res.json({
status:0,
message:"Successfully saved",
path : image
})
}
})
im triying to upload a file with multer but always the req.file is undefined and the destination folder is empty:
Server:
var express = require('express');
var multer = require('multer')
var app = express();
var storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, './public/uploads/'); // Make sure this folder exists
},
filename: function(req, file, cb) {
console.log(file)
var ext = file.originalname.split('.').pop();
cb(null, file.fieldname + '-' + Date.now() + '.' + ext);
}
}),
upload = multer({
storage: storage
}).single('avatar');
app.post('/uploads', upload, (req, res) => {
console.log('body', req.body);
console.log('file', req.file);
res.json("ok")
});
Client:
I've looked at many answers but nothing worked.
<form id="myform" encrypt="multipart/form-data">
<label for="userName">Name</label>
<input type="text" name="userName"/>
<br>
<label for="phoneNumber">PhoneNumber</label>
<input type="text" name="phoneNumber"/>
<br>
<label for="file">UploadFile</label>
<input type="file" name="avatar"/>
<input type="submit"/>
</form>
$('#myForm').submit(function(e){
var formData = new FormData($(this)[0]);
$.ajax({
type:'POST',
url:'uploads',
data : formData,
contentType: true,
processData: false
}).done(function(data){
//print response on success
console.log(data);
}).fail(function(data) {
console.log('Error');
});
e.preventDefault();
});
Can you tell me what i'm doing wrong please?
Why have you implemented $('#myForm').submit(function(e){...})?
You have a typo in your <form> element. The attribute is called enctype, not "encrypt". And you could simply add the method="POST" attribute and remove all javascript and let the browser to the upload.
Sample:
<form method="POST" action="/uploads" enctype="multipart/form-data">
.....
</form>
I found the error in the ajax I've to set the content type to false:
$('#myForm').submit(function(e){
var formData = new FormData($(this)[0]);
$.ajax({
type:'POST',
url:'uploads',
data : formData,
contentType: false, // <-----------------
processData: false
}).done(function(data){
//print response on success
console.log(data);
}).fail(function(data) {
console.log('Error');
});
e.preventDefault();
});
Thanks to #Marc.
I am having some problems uploading my image from a form to my s3 bucket. At present part of the image gets uploaded, so for example 19kb instead of the full 272kb, if i try and open the image from within my bucket it's broken
app.post('/admin/addClub', (req, res) => {
if (!req.user) {
res.redirect('/admin');
return;
}
// Upload image to S3
var s3Bucket = new AWS.S3( { params: {Bucket: process.env.AWS_BUCKET, Key: process.env.AWS_ACCESS_KEY_ID} } )
var data = { Key: req.body.imageBanner, // file from form
Body: req.body.imageBanner, // Not sure here
ACL: "public-read",
ContentType: helper.getContentTypeByFile(req.body.imageBanner)
};
s3Bucket.putObject(data, function(err, data){
if (err)
{ console.log('Error uploading data: ', data);
res.redirect('/admin/main');
} else {
console.log('succesfully uploaded the image!');
res.redirect('/admin/main');
}
});
Can anybody advise what i need to pass through for the Body key? as i think this must be my issue
Thanks
You need to integrate the express-fileupload package that allows you to receive file uploads on Express.
To install run: npm install --save express-fileupload
Then you'll need to pass req.files.imageBanner.data (supposing your file upload field looks like <input name="imageBanner" type="file" />) as the Body parameter. Here's how it should look:
var fileUpload = require('express-fileupload');
app.use(fileUpload());
app.post('/admin/addClub', (req, res) => {
if (!req.user) {
res.redirect('/admin');
return;
}
// Upload image to S3
var s3Bucket = new AWS.S3( { params: {Bucket: process.env.AWS_BUCKET, Key: process.env.AWS_ACCESS_KEY_ID} } )
var data = { Key: req.body.imageBanner, // file from form
Body: req.files.imageBanner.data,
ACL: "public-read",
ContentType: helper.getContentTypeByFile(req.body.imageBanner)
};
s3Bucket.putObject(data, function(err, data){
if (err)
{ console.log('Error uploading data: ', data);
res.redirect('/admin/main');
} else {
console.log('succesfully uploaded the image!');
res.redirect('/admin/main');
}
});
});
You can find the documentation for the express-fileupload package here:
https://www.npmjs.com/package/express-fileupload
Can anyone tell me How to upload files Using nodejs and HAPI?
I am getting binary data inside the handler.
Here is my html code:
function sendFormFromHTML(form) {
//form = $(".uploadForm").form;
var formData = new FormData(form);
formData.append('id', '123456'); // alternative to hidden fields
var xhr = new XMLHttpRequest();
xhr.open('POST', form.action, true);
xhr.onload = function(e) { alert(this.responseText) };
xhr.send(formData);
return false;
}
<form method="post" id="uploadForm" action="http://localhost:3000/api/uploadfiles" enctype="multipart/form-data">
<label for="upload">File (Binary):</label>
<input type="file" name="upload" class="fileupload" /><br/>
<input type="button" class="submit" value="Submit" onclick="sendFormFromHTML(this.form);"/>
</form>
Here is My Nodejs code:
server.route({
method: 'POST',
path: '/api/uploadfiles',
config: {
handler: currentposition.uploadFiles,
}
});
uploadFiles:function(req,reply){
console.log(req.payload);
}
For new readers, hapi already using multiparty uses pez to handle multipart post requests. From hapi documentation;
If the payload is 'multipart/form-data' and parse is true, fields values are presented as text while files are provided as streams. File streams from a 'multipart/form-data' upload will also have a property hapi containing filename and headers properties.
Example;
server.route({
method: 'POST',
path: '/create',
config: {
payload:{
maxBytes: 209715200,
output:'stream',
parse: true
},
handler: function (request, reply) {
request.payload["htmlInputName"].pipe(fs.createWriteStream("test"));
}
});
You can visit for working code in https://github.com/pandeysoni/Hapi-file-upload-download
/*
* upload file
*/
exports.uploadFile = {
payload: {
maxBytes: 209715200,
output: 'stream',
parse: false
},
handler: function(requset, reply) {
var form = new multiparty.Form();
form.parse(requset.payload, function(err, fields, files) {
if (err) return reply(err);
else upload(files, reply);
});
}
};
/*
* upload file function
*/
var upload = function(files, reply) {
fs.readFile(files.file[0].path, function(err, data) {
checkFileExist();
fs.writeFile(Config.MixInsideFolder + files.file[0].originalFilename, data, function(err) {
if (err) return reply(err);
else return reply('File uploaded to: ' + Config.MixInsideFolder + files.file[0].originalFilename);
});
});
};
Finally I got the solution to upload the large files using HAPI and Thanks to Roman.
Here is the solution:
server.js code
server.route({
method: 'POST',
path: '/api/uploadfiles',
config: {
payload:{
maxBytes:209715200,
output:'stream',
parse: false
},
handler: currentposition.uploadFiles,
}
});
Handler code:
var currentpositionApi = {
fs : require('fs'),
multiparty: require('multiparty'),
uploadFiles:function(req,reply){
var form = new currentpositionApi.multiparty.Form();
form.parse(req.payload, function(err, fields, files) {
currentpositionApi.fs.readFile(files.upload[0].path,function(err,data){
var newpath = __dirname + "/"+files.upload[0].originalFilename;
currentpositionApi.fs.writeFile(newpath,data,function(err){
if(err) console.log(err);
else console.log(files)
})
})
console.log(files)
});
}
}