As a self-learner on the way to learning. I sort out my understanding of knowledge by learning and sharing, and I also hope to give you a reference. I hope I can make progress together with you. If there is any mistake, I hope you can correct it. Thanks a million!


Earlier, we set up a static file server. The user requests a specified file stored on the server by entering a URL in the browser search bar. But servers can do a lot more than just serve static files. In this article, we’ll learn how to use Node.js to handle information submitted from HTML forms in front pages.

Set up the routing

On a daily basis, when we visit different addresses on a site, the content of the page usually changes accordingly. This is because the server, in order to achieve more functionality, will do different things depending on the REQUESTED URL, which is called “routing”.

“Routing” is simply a mapping between requests and request-handling code. When the server hangs on the request handling code for a particular URL, all requests for that particular URL are processed by it.

Suppose we want to create a personal web page to introduce ourselves, including: “home page “,” project introduction page “, “About me page “.

Then we can set up routing rules as shown in the following code:

// Introduce related modules
var http = require('http');
var url = require('url');

// Set up the HTTP server
var server = http.createServer(function(req, res) {
    // Get the request URL and match the corresponding processing method according to the pathname in the URL.
    var urlObj = url.parse(req.url);
    var urlPathname = urlObj.pathname;

    switch (urlPathname) {
        case "/main":
            // Do not forget to specify the encoding method because the returned content has Chinese characters
            res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" });
            res.write("Home page");
            res.end();
            break;
        case "/aboutme":
            res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" });
            res.write(About me page);
            res.end();
            break;
        case "/projects":
            res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" });
            res.write("Project Introduction Page");
            res.end();
            break;
        // If neither match, return 404
        default:
            res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
            res.write("404 - Not Found");
            res.end();
            break; }});// Listen for requests on port 3000
server.listen(3000.function() {
    console.log("Server running.");
    console.log("Listening on port 3000 :")})Copy the code

The above code hands the request to a different processing code depending on the requested URL. You can try running the server and then using the browser to request the URL and see what the response is.


GET the GET form submission

Now that we’ve learned about routing, let’s look at how to get form submissions sent from the client.

Let’s start with the form submitted using the GET method. The form content submitted via GET is assembled into a “query string” embedded in the request URL. Take this for example:

https://www.zhihu.com/search?type=content&q= canned soda GarrikCopy the code

From? The question mark starts out as the query string for this URL; Parameters are separated by &; = The name of the parameter is preceded by the value of the parameter.

The query string from the URL is parsed as JSON:

{
    "type": "content"."q": "Canned soda Garrik."
}
Copy the code

Now that you’ve covered the basics, let’s start writing code!

Let’s start by writing a page with an HTML form and name it login.html (you can code and name it however you want)

This is the form I want to use to submit the login information, and the action property of the form element is defined as login, which means to send the request to login, and the method property is defined as GET, which means to submit the form using the GET method.

<body>
    <form action="login" method="get">Account:<input type="text" name="username" />
        <br />Password:<input type="text" name="password" />
        <br />
        <input type="submit" value="Submit">
    </form>
</body>
Copy the code

Let’s write the server code later. From the previous introduction, you know that we need to parse the query string of the URL. This is easy to do by passing the second argument true when the url.parse function is called to parse the request URL. This function automatically parses the URL query string into a JavaScript object, stored in the query property of the object returned by the function. The property value is null if there is no query

We can use routing to match paths, and when the path of the request URL matches the path of the form, we hand the request to specific code to handle.

var server = http.createServer(function(req, res) {
    // Parse the request URL
    var urlObj = url.parse(req.url, true);
    // Get the path to the requested URL
    var urlPathname = urlObj.pathname;
    // Get the object parsed into the query string that requested the URL
    var queryObj = urlObj.query;
    
    / / routing
    switch (urlPathname) {
        // Respond to the login page
        case "/":
        case "":
            // I used the static server module. If you don't know about it, you can refer to it
            readStaticFile(res, "./login.html");
            break;
        // Respond to the query object in JSON form to the browser
        case "/login":
            res.writeHead(200, { "Content-Type": "text/plain" });
            res.write(JSON.stringify(queryObj));
            res.end();
            break;
        // Error handling
        default:
            readStaticFile(res, "./404.html"); }});Copy the code

When the server is up and running, visit the login page and submit the form and you should see something like this:


Gets the POST form submission

With GET out of the way, let’s talk about submitting the form using POST. Unlike GET, the submitted content is contained in the URL. All the content submitted by POST is in the request body.

The request object req received by our HTTP server http.createserver does not have an attribute content for the request body. The reason is that the body of a POST request can be very large, and it would be time-consuming to include the body every time a request is received. And in the event of a malicious POST request attack, the server’s resources are wasted.

To get the body of the POST request, we need to do this manually. Since a POST request can be a large amount of data, it is broken up into many small chunks. We receive these chunks one by one and splice them together by listening for the ‘data’ event of the request object REQ on the server.

When the request is transmitted, the ‘end’ event of the request object REq is emitted. We need to listen for it, and when the event fires, parse the request body of the POST in its event handler.

var server = http.createServer(function(req, res) {
    var urlObj = url.parse(req.url, true);
    var urlPathname = urlObj.pathname;

    switch (urlPathname) {
        case "/":
        case "":
            readStaticFile(res, "./login.html");
            break;
        case "/login":
            // Emitted when the request method is POST
            if (req.method === 'POST') {
                // Save the spliced request body
                var post = ' ';
                // The 'data' event is emitted to concatenate the received chunk of data to the POST variable
                req.on('data'.function(chunk) {
                    post += chunk;
                });
                // The request completes, and the 'end' event is emitted
                req.on('end'.function() {
                    // QueryString is a built-in node. js module, and the parse method is used to parse query strings into objects
                    var queryObj = querystring.parse(post);
                    // Respond the received POST request body back to the client in JSON format
                    res.writeHead(200, { "Content-Type": "text/plain" });
                    res.write(JSON.stringify(queryObj));
                    res.end();
                });
            }
            break;
        default:
            readStaticFile(res, "./404.html"); }});Copy the code

Oh, and most importantly, don’t forget to change the form submission method in the login.html file from GET to POST

<body>
    <form action="login" method="post">
        <! -- Omitted -->
    </form>
</body>
Copy the code

Now run the server, submit the form, and see what the results are. It should look something like the following:


POST File uploading

File uploads can be easily done using the third-party module Formidable.

First use NPM to install the module:

npm install formidable --save
Copy the code

Formidable is a module for form data parsing, perfect for file upload processing. To use this module, its IncomingForm constructor initial module is called. This function returns an IncomingForm instance that is used to process the form submission data. The data is then parsed by calling the instance’s parse method.

When a user submits data using a form, the form may contain two types of data: regular form data and file data. The parse method puts these two types of data into the fields and Files callback parameters, respectively.

So no more nonsense directly on the code:

// Module import
var formidable = require('formidable');

var server = http.createServer(function(req, res) {
    var urlObj = url.parse(req.url, true);
    var urlPathname = urlObj.pathname;

    switch (urlPathname) {
        case "/":
        case "":
            readStaticFile(res, "./upload.html");
            break;
        // Route to '/upload'
        case "/upload":
            if (req.method === 'POST') {
                // Initialize the IncomingForm instance of formidable
                var form = new formidable.IncomingForm();

                // uploadDir sets the location of temporary files when uploading files
                form.uploadDir = "./uploads";
                The keepExtensions property sets whether to keep the extension of the uploaded file. The default is false
                form.keepExtensions = true;
                
                // Start parsing
                form.parse(req, function(err, fields, files) {
                    if (err) {
                        var message = "File parsing failed";
                    } else {
                        var message = "File uploaded successfully";
                    }
                    res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8"}); res.write(message); res.end(); })}break;
        default:
            readStaticFile(res, "./404.html"); }});Copy the code

After the server code is written, let’s write the upload.html file:

<body>
    <form action="upload" enctype="multipart/form-data" method="post">
        <input type="file" name="upload" />
        <br />
        <input type="submit" value="Submit">
    </form>
</body>
Copy the code

Note that the encoding mode of the form to be set is encType “multipart/form-data”. The default encoding mode of the form data is “Application/X-www-form-urlencoded”, which cannot be used for file uploading. When using forms that contain file upload controls, you must use the value “multipart/form-data”.

Once you’ve written it, run the server, upload a photo you like, and see what comes up. Here is my operation:

You can see that the photo has been uploaded to uploads.

GET vs POST

We submitted the form using GET and POST methods, so what’s the difference between the two methods?

Let’s take a look at MDN’s definition of these two methods:

  • HTTP GET method: requests a specified resource. Requests using GET should only be used to GET data
  • HTTP POST method: sends data to the server

As simple as it is, use the GET method when you want to request a resource from the server. Use the POST method when sending data. Using the GET method to submit login information, as I did earlier, is not compliant with the specification. In real development, this behavior is not allowed.

With that definition out of the way, let’s look at the performance differences between the two methods.

  • As an observant you must have noticed, the form data submitted by GET is explicitly added to the query string of the requested URL. POST places the submitted data in the body of the request. This is why GET can’t be used to transfer data. You don’t want your account and password to be exposed in the URL so obviously.

  • Browsers have limits on the length of urls. Therefore, the size of data submitted by GET is limited to 1024 bytes. In theory, there is no limit to the size of the data that a POST submits. However, for the sake of performance, the server may limit the size of data transmitted by POST.


😆 Well, that’s the end of today’s sharing. In the next article, I’ll introduce you to the template engine.

If you like it, just click on it! O(∩_∩)O Thanks for your support ❗️