How to get uploaded file in Node.js Express app using angular-file-upload - node.js

I want to upload a file using angular-file-upload. But when I try to access req.body.files or req.files i get undefined.
Can anybody tell me how to get the file which is uploaded through angular-file-upload in node.js express app ?
Request Payload is as below:
Content-Disposition: form-data; name="myFile"; filename="BroadcomLogo.gif"
Content-Type: image/gif
JS Code:
$scope.upload[index] = $upload.upload({
url : '/upload',
method: 'POST',
file: $scope.selectedFiles[index],
fileFormDataName: 'myFile'
});
Node Code
upload: function(req, res) {
console.log(req.files);
res.send("Hello");
},

You need to use a middleware that parses files from a request in Node.js:
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();
app.post('/upload', multipartMiddleware,upload);
Simply put, middleware are functions that handle requests. A server
created by connect.createServer can have a stack of middleware
associated with it. When a request comes in, it is passed off to the
first middleware function, along with a wrapped ServerResponse object
and a next callback. Each middleware can decide to respond by calling
methods on the response object, and/or pass the request off to the
next layer in the stack by calling next().
http://stephensugden.com/middleware_guide/
In the case of the multipart middleware, it will call the next() method so you can write your own function to respond to the request.
Of course you need to install it first: npm install connect-multiparty
They are other middlewares that handle multipart uploads:
busboy and connect-busboy
multiparty and connect-multiparty
formidable
multer
You should probably use one that is compatible with connect, as express is built on top of connect

Access it in the files object with the name attribute as the key:
req.files.myFile

Related

How to get req.body from Facebook's data deletion URL call?

I've implemented the "sign in with Facebook" authorization method for my Express.js Node app. Since the app is hosted in the EU, Facebook requires it to have a data deletion request callback URL.
I've created an endpoint for the data deletion request, but whenever I make Facebook call that endpoint both req.body and req.query are empty - if I've understood correctly the body should contain a signed_request that could be used to e.g. verify the caller.
My CORS settings should be fine and I've tested my endpoint by calling it from Postman. The endpoint is able to receive a POST request with a JSON body without any problem.
So, what am I doing wrong - why does it seem like Facebook is calling my endpoint with a POST request that has an empty body?
My endpoint:
import express from 'express'; // 4.17.1
const router = express.Router();
router.post('/fb_data_deletion', (req, res, next) => {
console.log(req.body); // {}
console.log(req.query); // {}
if (!req.body || !req.body.signed_request) {
console.log('Bad request'); // Ends up here whenever Facebook calls this route
return req.sendStatus(400);
}
// verify request, delete user's data + other code here
});
Turns out Facebook isn't sending a POST request that uses Content-Type application/json but application/x-www-form-urlencoded.
To get the body of Facebook's POST request I had to add the following line to my app.js where the Node server is being set up:
app.use(express.urlencoded());

How to handle expressjs middleware request. POST request remains pending made by dropzone

I am using dropzone to upload the file. On the server side I am using node and expressjs. I am also using multer as the file handling middleware.
dropzone makes a call to one endpoint to save the file on the server.
On the server side, I created an endpoint to handle the file:
exports.saveFile = function (req, res) {
console.log(req.files);
return res.status(200);
//I have not added any file save logic here
};
This is how I have configured multer
var app = express();
var server = require('http').createServer(app);
app.use(multer({ dest: './uploads/'}));
Looks like multer automatically saves the file into the uploads folder.
Problem: Even though the file is saved on the server, the request remains in pending state on the client side.
How can I return success response from the server to the client?
Do I need to add some code on the endpoint I have created or I need to add required logic under onFileUploadComplete() given by multer?
You need an Express route for your form post that will finish the http request. The multer middleware will process the file uploads and add them to the request so they are available to a route handler, but you need to have a route for the form post.
From the multer example on this page, you can do something like this for your route:
app.post('/myform', function(req, res){
console.log(req.body); // form fields
console.log(req.files); // form files
res.status(204).end()
});

Can't POST (and parse) params to app.post() in express.js

I checked this question but for some reasons the solution given is not working for me. In my express.js I have:
...
bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
...
Run test using POSTman
app.post('/upload', function(req, res) {
console.log(req.body) // undefined
console.log(req.params) // undefined
})
and the result:
So both body & params are empty. Any suggestions?
The reason the solution in the link you provided doesn't work is because that version of body-parser is out of date and doesn't include form-data parsing anymore (and it used to be bundled with express).
With that being said, based on your screenshot, it looks like you are sending data of type multipart/form-data(you can check this in the request headers) to your server and your code sample only shows middleware that handles urlencoded and json data types.
You need to add middleware that handles that data type. The latest body parser says (https://github.com/expressjs/body-parser):
This does not handle multipart bodies, due to their complex and
typically large nature. For multipart bodies, you may be interested in
the following modules:
busboy and connect-busboy
multiparty and connect-multiparty
formidable
multer
So check out one of the above parsers. I use busboy and it works great.

How to test POST request parameters an Express app using supertest?

I'm creating an API using Express 4.0.0 and one of the routes takes a POST. Currently I'm just trying to have it echo a name sent in the request parameters. The response is a JSON object, but the request expects form fields.
users.post '/user', (req, res) ->
res.json name: req.params.name
My test sets the type() to form which should allow send() to pass the hash as POST parameters/fields.
describe 'POST /user', ->
it 'should echo the name sent', (done) ->
request app
.post '/user'
.type 'form'
.send name: 'Foo'
.expect '{"name":"Foo"}'
.end done
Regardless, my test fails and in Express, my req.params is empty, req.param('name') comes up undefined and req.body is also empty.
Is there some req.fields attribute I'm not aware of, or is my test flawed somehow?
tl;dr: You need to parse the body to get that, you can do app.use(require('body-parser')()) and then change your code with name: req.param('name').
So express(and actually node.js http server) will call the request call whenever a http request header have been received and not the body of the request. You have to explicitly read and wait for the body to come and parse it yourself.
Luckily there are express middleware modules that parses the body for you. In this case you are sending a urlencoded/form body, so you need to parse it as such. Use any of these modules according to their examples:
body-parser
body
Assuming you use body-parser, then if you want it to parse the body for all routes then just do app.use(require('body-parser')(). If you want it to parse the body for a particular route then do this:
bodyParser = require('body-parser')()
app.post '/user', bodyParser, (req, res) ->
res.json name: req.param('name')
Once you got the body parsing right, then you can access it either through req.body(for example req.body.name) property or req.param function(for example req.param('name')). The latter will also search through query string and url parameters.
Note that if you want to parse a body with attached files(for uploading files) you need a multipart parser and not just a urlencoded one:
connect-multiparty
connect-busboy

relation between front-end functions and server routes in node.js

Inexperienced with nodejs style programming, I'm looking at an open-source node.js app that has routes with the same paths in both the front-end main.js file and the routes.js file, as you see below. I'm assuming that when the function in main.js file gets called it triggers the route in routes.js, however, I can't figure out what if anything is getting passed from main.js to routes.js as a callback.
main.js
$.get('/ip', function (data) {
fp.val(fingerprint);
userId.val(md5(fingerprint + data.ip));
});
routes.js
app.get('/ip', function (req, res) {
res.json({
ip: req.connection.remoteAddress
});
});
There's nothing node-specific about the frontend script, it's just using jQuery.get to get the document at a given URL.
On the server-side, it looks like the app is using Express (or something like it) which modifies the .send() method of the response to allow sending arbitrary objects. When you send and object, Express JSON encodes it (using JSON.stringify(object) and sets the Content-Type header of the response to application/json. This content-type header is what tells jQuery to automatically parse the JSON response back into an object in the browser.
So there is no callback being passed from main.js to routes.js, it's just a bog-standard web request that sends JSON data back to the client.

Resources