I'm developing a web application using nodejs server-side. I'm trying to send pdf files from client to server.
Client:
var files = new FormData();
var count = 0;
$('#tableSlideId tr').each(function() {
var inputForm = $(this).find("th:first").children();
file = inputForm[0].files[0];
files.append((count++).toString(),file);
});
$.ajax({
type: "POST",
url: "/sendFiles",
data: files,
contentType: false,
processData: false,
}).done(function(err){
var text ="";
if(err) {
text = "Upload FAILED! Retry ...";
} else {
text = "Upload SUCCES!";
}
alert(text);
});
I think the client side is ok, infact if I use this loop:
for(var p of files)
console.log(p);
I correctly visualize all the elements that I want to send to the server.
Server:
app.post('/sendFiles', function(req,res) {
console.log("--->",req.body);
res.end();
});
Now in the server I have no idea how to visualize the data that I send, infact req.body is empty.
I don't know if this is the right way but my goal is to load some pdf files form the client, send to the server and after store them in a mySql dmbs.
Thank you.
Use express-formidable module. install 'express-formidable' by the running command
npm install express-formidable --save
a simple example is as follows from github
const express = require('express');
const formidable = require('express-formidable');
var app = express();
app.use(formidable());
app.post('/upload', (req, res) => {
//req.fields contains non-file fields
//req.files contains files
console.log(req.fields);
console.log(req.files);
});
Hope this helps!
Edit, from here -
app.post('/submit-form', (req, res) => {
new formidable.IncomingForm().parse(req, (err, fields, files) => {
if (err) {
console.error('Error', err)
throw err
}
console.log('Fields', fields)
console.log('Files', files)
files.map(file => {
console.log(file)
})
})
})
I think you need some middleware to accept the multipart formdata in the server side. Multer is a good option.
You can use
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })
and then update your server side to handle the upload:
app.post('/sendFiles', upload.array('files', maxCount), function(req,res)
Related
I am working on an MEAN Stack application and I am trying to manage a form that allows users to upload a file when they submit. It appears to be working on the client side, however when I send the post request from the client and inspect the request body the file is an empty object. It is just a small .docx file so it should be fine size-wise. But I do not understand why nothing is properly received since the request goes through with out error. I was under the impression that files could be sent this way.
Am I missing something?
code from angular service
sendApplcation(data : any): Observable <any>
{
return this.http.post(this.url+ '/careers/api/application', data);
}
nodejs code
router.post("/api/application", (req, res) => {
const application = req.body;
console.log(req.body.file);
let email = {
to: `${req.body.email}`,
from: "Careers#TrueLogistics.ca",
subject: "Application Recieved",
text: JSON.stringify(req.body),
html: `<p> ${JSON.stringify(req.body)} </p>`,
};
mailer.sendMail(email, (err, res) => {
if (err) {
console.log(err);
}
});
email.to = "mjayfalconi#gmail.com";
mailer.sendMail(email, (err, res) => {
if (err) {
console.log(err);
}
});
res.json("Applcation Submitted Successfully!");
});
Check out the multer package on npm.
File upload works a bit differently than the normal request.
You will also set enctype to multipart at the front end.
Furthermore, I see you are using nodemailer to send the file as an attachement. Read the documentation about the attachment. You don't send the file that way.
//Dependencies
const multer = require('multer');
//Multer DiskStorage Config
const diskStorage = multer.diskStorage(
{ destination: 'assets/profile_upload'} );
//Create Multer Instance
const upload = multer({ storage: diskStorage });
//File upload
//or app.post()
router.post('/upload-file', upload.single('file'), (req, res) => {
//The file
console.log(req.file)
;});
//Your code:
app.post('/upload', (req, res) => { ... try doing app.post('/upload' ,upload.single('file'),
Also check out this post: https://stackoverflow.com/a/61341352/9662626
Sorry for the bad formatting. I only have access to my phone at the moment.
Client code:
var data = new FormData();
data.append(fileName, blob, 'test.html');
fetch('http://localhost:3000/', {
method: 'POST',
headers: {
},
body: data
}).then(
response => {
console.log(response)
}
).then(
success => {
console.log(success)
}
).catch(
error => {
console.log(error)
}
);
Server code:
router.post('/', urlencodedParser, function(req, res, next) {
const body = req.body;
console.log(body);
res.send(`You sent: ${body} to Express`);
});
I am sending a blob in the body of a post request. When I send it to the server I want the server to download the file from the body of the request. How can i download this file? Or is there a simpler way to upload from client?
If you can utilize an NPM package formidable, there appears to be a solution at: https://www.w3schools.com/nodejs/nodejs_uploadfiles.asp
Once you have the file received, you can use the fs module to save and store in server
May it can solve your problem.
const fs = require('fs');
let directory = '/temp/data'; // where you want to save data file
router.post('/', urlencodedParser, function(req, res, next) {
const body = req.body;
console.log(body);
fs.writeFile(directory, body, function(err) {
if(err) {
return console.log(err);
}
console.log("File has been saved");
});
res.send(`You sent: ${body} to Express`);
});
This solved my answer - https://attacomsian.com/blog/uploading-files-nodejs-express, which basically uses a middleware to do the upload.
This was basically like:
const x = 6;
console.log(x);
Error: value is f'd up
const x = 6;
magic.valueParse(x);
console.log(x);
6
Also, i would like to point out how bodyParser cannot be used for multipart data. It is mentioned on the official docs, but even responses I get seem to point to bodyParser. So I thought I'd re-iterate that.
I am trying to use the fastify-multer plugin to upload files to the server and I am able to successfully get the images uploaded to the folder.
The problem is my app crashes.
I used the fastify-cli generated structure and I am running it as a standalone server as mentioned in the README.md here.
I am writing it as a fastify plugin.
"use strict";
const fp = require("fastify-plugin");
module.exports = fp(function(fastify, opts, next) {
fastify.decorate("uploadImage", function(request) {
const path = require("path");
const multer = require("fastify-multer");
var storage = multer.diskStorage({
destination: path.join(path.join(__dirname + "/uploads/")),
filename: function(request, file, cb) {
cb(null, file.originalname);
}
});
var upload = multer({ storage }).single("myImage");
upload(request, function(err) {
if (err) {
console.log(err);
} else {
console.log("Saved...");
return { saved: true };
}
});
});
next();
});
And here is the error I get :
Hi looked into your issue. You are using fastify-multer in the wrong way.
Invoking multer({ storage }).single("myImage") you are creating a fastify's preHandler hook that accepts 3 specific parameters. You can find more on the offical documentation. A simple working example could be the one you can see at fastify-multer:
const server = fastify()
// register fastify content parser
server.register(multer.contentParser)
server.route({
method: 'POST',
url: '/profile',
preHandler: upload.single('avatar'),
handler: function(request, reply) {
// request.file is the `avatar` file
// request.body will hold the text fields, if there were any
reply.code(200).send('SUCCESS')
}
})
If you need more help just provide me a repro repo on github and I'll try to figure out what is the best solution for your case.
Let me know! :)
I am trying to upload a file to my server, but req.file and req.files is always undefined on my POST REST endpoint.
The content I'm trying to upload is a ".dat" file, and I am expecting a json response.
Here's my code:
Server side:
var express = require('express');
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })
var app = express()
app.post('/creoUpload', upload.single('uploadFileField'), function(req, res, next) {
console.log("req.file = ",JSON.stringify(req.file)); //is undefined
console.log("req.files = ",JSON.stringify(req.files)); //also undefined
});
Client Side:
<form id="creoUploadForm" action="/creoUpload" enctype="multipart/form-data" method="post">
<input type='file' name='uploadFileField'><br><br>
<input type='submit' value='Upload'/>
</form>
JS:
$( "#creoUploadForm" ).submit(function( event ) {
event.preventDefault();
var formData = new FormData($(this)[0]);
$.ajax({
url: '/creoUpload',
type: 'POST',
data: formData,
async: true,
cache: false,
contentType: false,
processData: false,
success: function (returndata) {
console.log("RETURN DATA IS: ",returndata);
},
error: function (err) {
console.log("ERROR: ",err);
}
});
});
I keep playing around with the fields but it's not working.. anyone see what I'm doing wrong here?
I'm following the example from https://www.npmjs.com/package/multer
Versions:
Express Version: 4.12.0
Node Version: 6.5.0
JQuery: 1.12.1
Thank you!
You are using multer as a middleware, So before entering into your function and printing it has uploaded images to storage and removes record from req.files.
There are two ways you can access req.files.
Use multer as a function stated by finw3.
Another solution is:
//CODE STARTS
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '/filepath')
},
filename: function (req, file, cb) {
let filename = 'filenametogive';
req.body.file = filename
cb(null, filename)
}
})
var upload = multer({ storage: storage })
//CODE ENDS
Now you can access files in req.body.file
I have the same issue, if you check the documentation on the Error Handling section there is another kind of implementation, that's the one that works for me. The code will be something like this:
var express = require('express');
var multer = require('multer');
var upload = multer({ dest: 'uploads/' });
var app = express();
app.post('/creoUpload', function(req, res, next) {
upload(req, res, function (err) {
if (err) {
// An error occurred when uploading
console.log('Err: ', err);
return;
} else {
console.log('req.file: ', JSON.stringify(req.file));
console.log('req.files: ', JSON.stringify(req.files));
return;
}
})
});
Don't set contentType to false, as POST method requires contentType = 'w-xxx-form-urlencoded', which is the JQ default.
If the req.file and req.files are undefined, then the problem is that multer did not receive the uploaded file and this issue seems related to jQuery.
Uploading a FormData with jQuery 'v1.12.1' is not supported and it won't send anything at all.
I will recommend to try with fetch Api or change the version of your jQuery to 3.3.1.
I already tested the code and I have successfully upload a file to my server when I change my jQuery version from v1.12.1 to v3.3.1.
I am now using angular-file-upload packages to upload files. After I press item.upload(), it claims to be successfully uploaded the file, but I see the req.body is empty. Please Help!
Here is the angular code to handle it:
var uploader = $scope.uploader = $fileUploader.create({
scope: $scope, // to automatically update the html. Default: $rootScope
url: '/api/teams/upload',
formData: [
{ key: 'value' }
],
filters: [
function (item) { // first user filter
$scope.previewImage(item);
return true;
}
]
});
And here is the way to trigger the upload:
uploader.bind('afteraddingfile', function (event, item) {
// console.info(item.file);
console.info('After adding a file', item);
// console.log('item.upload();');
item.upload();
});
And finally here is the express js code:
exports.upload = function(req, res) {
// console.log('req.headers');
// console.log(req.headers);
console.log('req.body');
console.log(req.body);
What wrong's with it?
First make sure your POST is encoded as enctype="multipart/form-data"....
In Express 4 you need to set the body parser in your server:
var bodyParser = require('dy-parser');
//...
var app = express();
//...
app.use(bodyParser()); // pull information from html in POST
var busboy = require('connect-busboy');
app.use(busboy());
In earlier version of Express you only needed to add the body parser from the framework itself and files will be store on the configured location:
app.use(express.bodyParser({limit: '10mb', uploadDir: __dirname + '/public/uploads' })); // pull information from html in POST
Since version 4 removed support for connect now you need to add your custom support for multipart/form data to parser multi/part POSTs, so you will have to to do something like:
var fs = require('fs');
var busboy = require('connect-busboy');
//...
app.use(busboy());
//...
app.post('/api/teams/upload', function(req, res) {
var fstream;
req.pipe(req.busboy);
req.busboy.on('file', function (fieldname, file, filename) {
console.log("Uploading: " + filename);
fstream = fs.createWriteStream(__dirname + '/files/' + filename);
file.pipe(fstream);
fstream.on('close', function () {
res.redirect('back');
});
});
});
On the client side you need to call the $upload.upload To start the upload