Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pure Node.js file upload (multipart POST) without using a framework

Tags:

node.js

The third-party libraries "node-formidable" and "express" come with the ability to handle multipart POST requests (e.g. with a file upload form), but I don't want to use any third-party code. How do I make the file upload process in pure JavaScript on Node.js?

There are very few resources in this regard. How can this be done? Thank you, love is.

like image 493
batuhangoksu Avatar asked Mar 23 '14 22:03

batuhangoksu


People also ask

How do you use bodyParser without express?

To parse the POST request body in Node JS without using Express JS body-parser, We have to listen events, emitted by the request, ie. 'data' event and 'end' event. Above we are using Buffer. concat(), it is a method available in Node JS Buffer class, it join all the received chunks and returns a new Buffer.

How can I upload a file without form?

Approach 1: This approach is to use FormData that can upload a file without using any kind of form. The special thing about this is that network methods, such as fetch, can accept a FormData object as a body. It's encoded and sent out with Content-Type — multipart/form-data.

How do you send a file using multipart form data?

Multipart form data: The ENCTYPE attribute of <form> tag specifies the method of encoding for the form data. It is one of the two ways of encoding the HTML form. It is specifically used when file uploading is required in HTML form. It sends the form data to server in multiple parts because of large size of file.

Can I use Ajax in node JS?

This can be done by Ajax request, we are sending data to our node server, and it also gives back data in response to our Ajax request. Step 1: Initialize the node modules and create the package. json file using the following command.


1 Answers

Just to clarify because it seems some people are angry that the other answer didn't help much: There is no simple way of doing this without relying on a library doing it for you.

First, here's an answer to another question trying to clarify what happens on a POST file upload: https://stackoverflow.com/a/8660740/2071242

To summarize, to parse such an upload, you'll first need to check for a Content-Type header containing "multipart/form-data" and, if one exists, read the boundary attribute within the header.

After this, the content comes in multiple parts, each starting with the boundary string, including some additional headers and then the data itself after a blank line. The browser can select the boundary string pretty freely as long as such byte sequence doesn't exist in the uploaded data (see the spec at https://www.rfc-editor.org/rfc/rfc1867 for details). You can read in the data by registering a callback function for the request object's data event: request.on('data', callback);

For example, with boundary "QweRTy", an upload might look something like this:

POST /upload HTTP/1.1
(some standard HTTP headers)
Content-Type: multipart/form-data; boundary=QweRTy

--QweRTy
Content-Disposition: form-data; name="upload"; filename="my_file.txt"
Content-Type: text/plain

(The contents of the file)
--QweRTy--

Note how after the initial headers two dashes are added to the beginning of each boundary string and two dashes are added to the end of the last one.

Now, what makes this challenging is that you might need to read the incoming data (within the callback function mentioned above) in several chunks, and there are no guarantees that the boundary will be contained within one chunk. So you'll either need to buffer all the data (not necessarily a good idea) or implement a state machine parser that goes through the data byte by byte. This is actually exactly what the formidable library is doing.

So after having similar considerations, what I personally decided to do is to use the library. Re-implementing such a parser is pretty error-prone and in my opinion not worth the effort. But if you really want to avoid any libraries, checking the code of formidable might be a good start.

like image 180
J.Nieminen Avatar answered Sep 19 '22 14:09

J.Nieminen