Nodejs Book: Chapter 9

In the previous chapter we uploaded form data and returned the raw string. In
this chapter, we will continue to expand on the last chapter by converting the
data from the uploading form into a JSON string. Lets take a look at the string
we returned to the client.

-----------------------------2285823208496
Content-Disposition: form-data; name="username"

my_username
-----------------------------2285823208496
Content-Disposition: form-data; name="email"

my_email@example.com
-----------------------------2285823208496
Content-Disposition: form-data; name="password"

12345678
-----------------------------2285823208496
Content-Disposition: form-data; name="phone_number"

080-2222-3333
-----------------------------2285823208496--

Form data has a boundary to distinguish between which fields have which values.
So the first step is to parse that out. The first line break in the string marks
the string that represents the boundary, and then separate the form into their
key value pairs.

Following that is the Content-Disposition which gives prudent information for
the type of data contained in the field. In this case it’s simply “form-data”,
but other options include attachments, or files, which we will attempt to
parse in the next chapter. But for the moment, we will simply assume key value
pairs and ignore this information.

The name is the name field from the original form. Nothing special here, but the
use of double quotations in this line allows us to use a regular expression to
extract this name from the given string.

Following that is two line breaks before the actual values being sent to the server
are included. Since these are the values we sent to the server, they should be
easily recognizable, or at the very least easily debug-able by entering different
values to determine their position in the form.

A sample implementation for parsing a basic form into a JSON object is as given
below.

function api_form( req, res ) {

    var str = "";

    req.on("data", function(data) {

        str += data;

    });

    req.on("end", function() {

        for(let i = 0; i < str.length; i++) {

            if(str[i] !== '\n'){
                continue;
            }

            let boundary = str.substr(0, i - 1);
            str = str.split(boundary);
            str.shift();
            str.pop();

            break;

        }

        let args = {};

        for(let i = 0; i < str.length; i++) {

            let field = str[i].split("\r\n");
            let key = field[1].match( /"(.*?)"/ )[1];
            args[key] = field[3];

        }

        str = JSON.stringify(args, null, 4);

        res.writeHead(200, { "Content-Type" : "text/plain" });
        res.end( str );

    });

}

The result of the function is as included below.

In the next chapter we will continue to look at forms and attempt to parse a
file out of form data.