Express - Uploading file through direct POST - node.js

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.

Related

multipart/form-data fetch post gives random output and multer can't extract file

I tried to upload an image file to my server. My client is writing with react native and server is node. I use fetch POST and multipart/form-data on the client side, and multer on server side. When I tried to console.log the request, I got a tons of trash information. I followed the example provided online so I have no idea what's going on. Also multer doesn't extract file from request (req.file is undefined). Also I don't really understand if you post local uri instead of base64 data to your server. How does the server know how to retrieve upload the file through local uri.

Express.js : What is the difference between res.attachment and res.download?

What is the difference between res.attachment and res.download and when to use which I am bit confused. In my case, I send my form data to the server as a JSON which will create a file out of it and respond with a download link. Which among the two: res.attachment and res.download should I use?
The res.attachment "Sets the HTTP response Content-Disposition header field to “attachment”."
This essentially says, 'Hey, this file should be viewed as an attachment, not a webpage.'
Whereas the res.download "Transfers the file at path as an “attachment”. Typically, browsers will prompt the user for download."
Find more about each HERE

Upload file on Express.js app

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

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.

How does Express handle routes, and what does the '#' do?

I've setup an Express server using backbone.js with a couple routes, and I'm trying to capture information through the url using req.params.
I've setup my server with appropriate routing
app.get( '/route/:first/:second', router.routeHandler );
With my express server, when I type in a url like this:
http://localhost:3000/route/firstVar/secondVar
I get raw JSON returned to me, but when I try a url like this:
http://localhost:3000/#route/firstVar/secondVar
it will actually render the html and CSS to the page. What is going on there? Can I change that behavior? Where is that setup?
Nothing after the hashmark is making its way to the server. If you want to be able to handle that second URL, you'll need to set up the proper routes on the client-side (in your case, using Backbone). Have a peek at Backbone's History and Router documentation for some more information.

Resources