Upload file on Express.js app - node.js

I'm developing a RESTful API for a mobile client application with the combination of Node.js, Express.js and Mongodb.
Now I'm trying to handle the upload of the user profile image and I've found a module called "multer" (that is the one ecommended by express.js team itself) that allow the express.app to handle multipart/form-data requests.
Now I need to test the app and, moreover, the upload function but I'm not able to simulate a http-form request (via postman chrome plugin).
Multer returns this error:
[Error: Multipart: Boundary not found]
In fact, comparing an http-form request (which works) with a custom http request, the second one has not the Boundary header property.
What Boundary property is?

If you are using Postman, you can try removing the Header: "Content-type": "multipart/form-data". I removed it and now it works.

Boundary in a multipart form indicates some delimiter string separating text and binary data. You can do this in postman but it sounds like you aren't sending both file and text so postman maybe defaults to a regular form. do you see something like:
If you click preview in postman you can see the boundary in the Content-type header and in the body.

solutions:
1) don't specify the content-type at client
2) use the naming convention(imageUpload) in upload.single('imageUpload') same as field name

Related

In ExpressJS, get original filename of a file sent with Body Binary in Postman

My pdf file is being sent to my server as binary data with Postman as seen in the picture attached.
The content of the file is being parsed on my ExpressJS server with req.on((chunk) => ...) etc.
Everything is fine, except the fact that I try to obtain the original filename(highlighted in red - valid-compressed-compressed.pdf) on the server, but I can't find the value anywhere in the request object.
Any suggestions, please?
Short answer: you cant.
If you look closely at the headers being sent with the request, there are no headers containing the filename. Therefore there are no headers you can access in express to retrieve that information. The only headers you send are Content-Type and Content-Length that gives some information about what you're sending. Other than that there's just the binary request body.
If you want to post a file and the filename you need to look into multipart/form-data (Multer).

Return file from GraphQL resolve

I am currently working on an application with the current tech stack:
Backend:
Mongoose
Express
Apollo
GraphQL
Frontend:
Vuejs
Apollo
GraphQL
I have succeeded in uploading files to the server using GraphQL, what I am stuck with is how to implement the 'download' feature. With a normal RESTApi endpoint I can use res.download(filePath) and it works. How do I do this with GraphQL since I don't want to use REST.
Or is there any other standard to go by in this scenario?
Thanks!
GraphQL uses JSON format, which represents as text format, not as binary.
If you don't want download files with REST, then you should:
Encode your file content into base64 string in the back end. Related question
Send this string as part of query response.
Save encoded base64 string as a file in the front end. Related question
But right architecture design is add a file link in the GraphQL response and use browser for downloading/rendering the file.
It's better to send a hashed & temporary link to download it
Save the file and hash the name on your static server (to limit access to other users)
The file should be temporary and should expire in a short time
Send the link of the file in response to API

Error handling in express based on how a resource is called?

I am using express.
I am handling a Get request like below.
router.get('/user', user.getSessionInfo);
On client side I am using Angularjs.
I want to customize my error handling in nodejs based upon how a resource is being called, i.e. when /user is called via an $http call or directly from browser url so that I can return(if an error happens) either a json error obj or an error page(html).
I tried using req.xhr to decide whether the call is an ajax or not but I am getting false in both cases(not getting X-Requested-With header via $http.get)
So to achieve my functionality Can I depend upon
req.headers['accept'];
as from ajax call it will be
"application/json, text/plain, */*"
and when called from the browser url bar it will be
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
Is my way the best or there is a better way of handling it?
There is another way,use query param(dot extension) to decide resource type:
GET /api/user.json
GET /api/user.html
GET /api/user.xml
and it seems than this solution is more complicated to achieve in Express.
req.xhr was removed in angular. Read here why removed and how to get it back
https://github.com/angular/angular.js/commit/3a75b1124d062f64093a90b26630938558909e8d

node.js body on http request object vs body on express request object

I'm trying to build an http module that suppose to work with an express server.
while reading the http module api, I see that it doesn't save the body inside the request object.
So my questions are:
If I want to build an express server which works with the official http module, how should I get the body?
I consider to implement the http module in the following way: listening to the socket, and if I get content-length header, listetning to the rest of the socket stream till I get all the body, save it as a memeber of the http request, and only then send the request object to the express server handler.
What are the pros and cons of my suggestion above vs letting the express server to "listen" to the body of the request via request.on('data',callback(data))
I mean , why shouldn't I keep the body inside the 'request' object the same way I keep the headers?
It's hard to answer your question without knowing exactly what you want to do. But I can give you some detail about how the request body is handled by Node/Express, and hopefully you can take things from there.
When handling a request (either directly via Node's request handler, or through Express's request handlers), the body of the request won't automatically be received: you have to open an HTTP stream to receive it.
The type of the body content should be determined by the Content-Type request header. The two most common body types are application/x-www-form-urlencoded and multipart/form-data. It's possible, however, to use any content type you want, which is usually more common for APIs (for example, using application/json is becoming more common for REST APIs).
application/x-www-form-urlencoded is pretty straightforward; name=value pairs are URL encoded (using JavaScript's built-in encodeURIComponent, for example), then combined with an ampersand (&). They're usually UTF-8 encoded, but that can also be specified in Content-Type.
multipart/form-data is more complicated, and can also typically be quite large, as vkurchatkin's answer points out (meaning you may not want to bring it into memory).
Express makes available some middleware to automatically handle the various types of body parsing. Usually, people simply use bodyParser, though you have to be careful with that middleware. It's really just a convenience middleware that combines json, urlencoded, and multipart. However, multipart has been deprecated. Express is still bundling Connect 2.12, which still includes multipart. When Express updates its dependency, though, the situation will change.
As I write this, bodyParser, json, urlencoded, and multipart have all been removed from Connect. Everything but multipart has been moved into the module body-parser (https://github.com/expressjs/body-parser). If you need multipart support, I recommend Busboy (https://npmjs.org/package/busboy), which is very robust. At some point, Express will update it's dependency on Connect, and will most likely add a dependency to body-parser since it has been removed from Connect.
So, since bodyParser bundles deprecated code (multipart), I recommend explicitly linking in only json and urlencoded (and you could even omit json if you're not accepting any JSON-encoded bodies):
app.use(express.json());
app.use(express.urlencoded());
If you're writing middleware, you probably don't want to automatically link in json and urlencoded (much less Busboy); that would break the modular nature of Express. However, you should specify in your documentation that your middleware requires the req.body object to be available (and fail gracefully if it isn't): you can go on to say that json, urlencoded, and Busboy all provide the req.body object, depending on what kind of content types you need to accept.
If you dig into the source code for urlencoded or json, you will find that they rely on another Node module, raw-body, which simply opens the request stream and retrieves the body content. If you really need to know the details of retrieving the body from a request, you will find everything you need in the source code for that module (https://github.com/stream-utils/raw-body/blob/master/index.js).
I know that's a lot of detail, but they're important details!
You can do that, it fairly simple. bodyParser middleware does that, for example (https://github.com/expressjs/body-parser/blob/master/index.js#L27). The thing is, request body can be really large (file upload, for example), so you generally don't want to put that in memory. Rather you can stream it to disk or s3 or whatnot.

Express - Uploading file through direct POST

I'm looking to implement an API similar to Imgur's upload feature: http://api.imgur.com/resources_anon#upload. In other words, a user should be able to upload an image by POSTing to /upload with an image file without using a form, ie through AJAX without setting the Content-Type header (just like Imgur). However, the only example I can find is the following: https://github.com/visionmedia/express/blob/master/examples/multipart/app.js
Question: How should I implement such an API? My concern is that Express won't interpret the command as multipart/form-data.
Assuming the client sets the upload request's Content-Type properly (which it will if the form used for the upload has the correct enctype attribute) and you use express.bodyParser(), express will handle everything correctly.

Resources