{"id":290,"date":"2020-06-10T10:06:06","date_gmt":"2020-06-10T01:06:06","guid":{"rendered":"https:\/\/blog.wsd.sh\/?p=290"},"modified":"2020-06-10T10:13:15","modified_gmt":"2020-06-10T01:13:15","slug":"nodejs-book-chapter-8","status":"publish","type":"post","link":"https:\/\/blog.wsd.sh\/?p=290","title":{"rendered":"Nodejs Book: Chapter 8"},"content":{"rendered":"<p>In the previous chapter we uploaded an image by sending the binary directly.<br \/>\nBut the issue was we able to send the information, but at the cost of losing<br \/>\ninformation on the filename. So if we want to have our cake and eat it too, we<br \/>\nneed a method of separating and parsing the information we send to and from<br \/>\nour server.<\/p>\n<p>Fortunately there is already a standard in place for doing this. When form data<br \/>\nis sent from a browser client to a server, the browser arranges the information<br \/>\nin being sent to the server in a method the server can parse and respond to. In<br \/>\nthis chapter, we&#8217;re just going to confirm the format in which information is sent<br \/>\nfrom the client to server. We will worry about parsing this information in the<br \/>\nnext chapter.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.wsd.sh\/wp-content\/uploads\/2020\/06\/fig_10-300x233.jpg\" alt=\"\" class=\"alignnone size-medium wp-image-291\" width=\"300\" height=\"233\" srcset=\"https:\/\/blog.wsd.sh\/wp-content\/uploads\/2020\/06\/fig_10-300x233.jpg 300w, https:\/\/blog.wsd.sh\/wp-content\/uploads\/2020\/06\/fig_10-1024x796.jpg 1024w, https:\/\/blog.wsd.sh\/wp-content\/uploads\/2020\/06\/fig_10-768x597.jpg 768w, https:\/\/blog.wsd.sh\/wp-content\/uploads\/2020\/06\/fig_10.jpg 1138w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>The file layout of this chapter&#8217;s code is listed below.<\/p>\n<pre>- callback.js\n+ public\/\n| - form.html\n| - + js\/\n| --- form.js\n<\/pre>\n<p>We have a pretty simple form.html, consisting of a form with a table and a few<br \/>\nexample fields, such as a username, email, password and phone number.<\/p>\n<p>File: form.html<\/p>\n<pre>&lt;!DOCTYPE HTML&gt;\n&lt;html&gt;\n\n    &lt;head&gt;\n\n        &lt;meta charset=\"utf-8\"\/&gt;\n        &lt;title&gt;Ajax Request&lt;\/title&gt;\n\n    &lt;\/head&gt;\n\n    &lt;body&gt;\n\n        &lt;form id=\"exampleForm\"&gt;\n            &lt;table&gt;\n                &lt;tr&gt;\n                    &lt;td&gt;Username:&lt;\/td&gt;\n                    &lt;td&gt;&lt;input type=\"text\" name=\"username\"\/&gt;&lt;\/td&gt;\n                &lt;\/tr&gt;\n                &lt;tr&gt;\n                    &lt;td&gt;Email:&lt;\/td&gt;\n                    &lt;td&gt;&lt;input type=\"text\" name=\"email\"\/&gt;&lt;br&gt;&lt;\/td&gt;\n                &lt;\/tr&gt;\n                &lt;tr&gt;\n                    &lt;td&gt;Password:&lt;\/td&gt;\n                    &lt;td&gt;&lt;input type=\"password\" name=\"password\"\/&gt;&lt;\/td&gt;\n                &lt;\/tr&gt;\n                &lt;tr&gt;\n                    &lt;td&gt;Phone Number:&lt;\/td&gt;\n                    &lt;td&gt;&lt;input type=\"text\" name=\"phone_number\"\/&gt;&lt;\/td&gt;\n                &lt;\/tr&gt;\n                &lt;tr&gt;\n                    &lt;td&gt;Submit:&lt;\/td&gt;\n                    &lt;td&gt;&lt;input type=\"submit\" value=\"Submit\"\/&gt;&lt;\/td&gt;\n                &lt;\/tr&gt;\n            &lt;\/table&gt;\n        &lt;\/form&gt;\n\n        &lt;br&gt;\n\n        &lt;pre id=\"responseText\"&gt;&lt;\/pre&gt;\n\n        &lt;script type=\"text\/javascript\" src=\"js\/form.js\"&gt;&lt;\/script&gt;\n\n    &lt;\/body&gt;\n\n&lt;\/html&gt;\n<\/pre>\n<p>Our Javascript also hasn&#8217;t changed much, but we use yet another method of<br \/>\nsending information. In this case we use the internal FormData Javascript object<br \/>\nto handle creating the form send request for us.<\/p>\n<p>File: js\/form.js<\/p>\n<pre>\"use strict\";\n\nvar exampleForm = document.getElementById(\"exampleForm\");\nvar responseText = document.getElementById(\"responseText\");\n\nexampleForm.addEventListener(\"submit\", function (event) {\n\n    event.preventDefault();\n\n    var formData = new FormData(exampleForm);\n\n    var xml = new XMLHttpRequest();\n    xml.open(\"POST\", \"\/api\/form\", true);\n    xml.send(formData);\n\n    xml.onload = function() {\n\n        responseText.textContent = xml.responseText;\n\n    }\n\n\n});\n<\/pre>\n<p>The reason event.preventDefault() is included because the default response<br \/>\nto a form submit, is for the browser to create, send a response to the server,<br \/>\nand then load a new page. In this case we handle everything with Javascript via<br \/>\najax, so we don&#8217;t want the browser to handle the event.<\/p>\n<p>File: callback.js<\/p>\n<pre>\"use strict\";\n\nconst fs = require(\"fs\");\nconst http = require(\"http\");\nconst uniqid= require(\"uniqid\");\nconst handleFile = require(\"handle-file\");\n\nconst server = http.createServer();\nserver.on(\"request\", handleRequest);\nserver.listen(8080, handleListen);\n\nfunction handleRequest(req, res) {\n\n    console.log(req.method);\n\n    if(req.method === \"GET\") {\n\n        handleFile(req, res);\n\n    } else if(req.method === \"POST\") {\n\n        switch(req.url) {\n            case \"\/api\/hello\":\n\n                api_say_hello(req, res);\n\n            break;\n            case \"\/api\/upload\":\n\n                api_upload_file( req, res );\n\n            break;\n            case \"\/api\/form\":\n\n                api_form( req, res );\n\n            break;\n            default:\n\n                res.writeHead( 204, { \"Content-Type\" : \"text\/plain\" });\n                res.end( \"Empty Response\" );\n\n            break;\n        }\n\n    } else {\n\n        res.writeHead( 204, { \"Content-Type\" : \"text\/plain\" });\n        res.end( \"Empty Response\" );\n\n    }\n\n}\n\nfunction handleListen( ) {\n\n    console.log(\"Server is listening on port 8080\");\n\n}\n\nfunction api_form( req, res ) {\n\n    var str = \"\";\n\n    req.on(\"data\", function(data) {\n\n        str += data;\n\n    });\n\n    req.on(\"end\", function() {\n\n        res.writeHead(200, { \"Content-Type\" : \"text\/plain\" });\n        res.end( str );\n\n    });\n\n}\n<\/pre>\n<p>Since we&#8217;re just debugging we have a very simple function for handling our form.<br \/>\nWe create a string and continue to add into it as we get content from the client.<br \/>\nAnd then we just return the string received from the client back to the client so<br \/>\nwe can display it in the browser.<\/p>\n<p>The content is as follows:<\/p>\n<pre>-----------------------------2285823208496\nContent-Disposition: form-data; name=\"username\"\n\nmy_username\n-----------------------------2285823208496\nContent-Disposition: form-data; name=\"email\"\n\nmy_email@example.com\n-----------------------------2285823208496\nContent-Disposition: form-data; name=\"password\"\n\n12345678\n-----------------------------2285823208496\nContent-Disposition: form-data; name=\"phone_number\"\n\n080-2222-3333\n-----------------------------2285823208496--\n<\/pre>\n<p>In the next chapter we will derive a function to parse this information.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this chapter of the Nodejs be continue to expand on the sending data to the server. In this example we create a form on the client side, and send the form via a POST request to the server, to unpack the body contents and return them to the client, so we can see how form data is encoded when sent to the server.<\/p>\n","protected":false},"author":1,"featured_media":249,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false},"categories":[4],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.wsd.sh\/index.php?rest_route=\/wp\/v2\/posts\/290"}],"collection":[{"href":"https:\/\/blog.wsd.sh\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.wsd.sh\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.wsd.sh\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.wsd.sh\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=290"}],"version-history":[{"count":3,"href":"https:\/\/blog.wsd.sh\/index.php?rest_route=\/wp\/v2\/posts\/290\/revisions"}],"predecessor-version":[{"id":295,"href":"https:\/\/blog.wsd.sh\/index.php?rest_route=\/wp\/v2\/posts\/290\/revisions\/295"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.wsd.sh\/index.php?rest_route=\/wp\/v2\/media\/249"}],"wp:attachment":[{"href":"https:\/\/blog.wsd.sh\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=290"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.wsd.sh\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=290"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.wsd.sh\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=290"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}