To read more articles in this series please visit myMaking a blog, sample code please visithere.

Creating a Server

Once routing is implemented, you can implement the server based on it.

Implementing the server is divided into the following steps:

Example code: /lesson28/lib/http.js

  1. Import the required Node.js modules, server configuration, and routing modules
  2. Encapsulates a unified approach to processing request data
  3. Received requests are classified into POST requests and GET requests, which are distinguished and processed
  4. POST requests are classified into data requests and file upload requests. They are distinguished and processed
  5. GET requests are divided into data requests and file read requests, which are distinguished and processed

Next, implement each part of the code step by step.

1. Import required Node.js modules, server configuration, and routing modules

Const HTTP = require(const HTTP = require('http')
const url = require('url')
const querystring = require('querystring')
const zlib = require('zlib')
const fs = require('fs')
const { Form } = require('multiparty'Const {HTTP_PORT, HTTP_ROOT, HTTP_UPLOAD} = require('.. /config'Const {findRouter} = require('./router') const server = http.createServer((req, Res) => {// Server code}) // Listen to the configured port server.listen(HTTP_PORT) // Print information about the success of creating the server console.log(' server started at${HTTP_PORT}`)
Copy the code

2. Encapsulate a unified approach to processing request data

To process all request interfaces, the required parameters are method (request method), pathName (request interface path), Query (Query data), POST (Post data), and files (file data).

First, according to method (request method), pathName (request interface path), get the callback function of the corresponding interface that has been configured during route configuration.

Second, if the callback function exists, the argument is passed directly to the callback function for processing.

Finally, if the callback function does not exist, the default is to request a static file that can be read and sent to the front end.

// Introduce the module needed to create the server... // Import server configuration... // Import the routing module to find the routing method... Const server = http.createserver ((req, res) => {// Async, a public method to process request data via routingfunctionprocessData(method, pathname, query, post, files) { const callback = findRouter(method, Pathname) // Get the callback function to handle the request // If the callback function exists, it indicates that the route is configured to handle the corresponding data, that is, the request is not to fetch a static file.if(callback) {try {// await callback(res, query, post) Files)} catch (error) {// Error handling res.writehead (500) res.write('Internal Server Error')
        res.end()
      }
    } else{// If the callback function does not exist, the request is a static file, such as HTML, CSS, JS, etc... }}}) // Listen to the configured port server.listen(HTTP_PORT) // Print the success message of creating the server console.log(' server started at${HTTP_PORT}`)
Copy the code

3. The received requests are classified into POST requests and GET requests

According to the method of the request, the request is divided into POST request and GET request.

If it is a POST request, you need to further determine whether it is a common data request or a file request and process them respectively.

A GET request, on the other hand, simply passes the data to the processData method for processing. In the processData method, the distinction is made between a GET request for data and a static file.

// Introduce the module needed to create the server... // Import server configuration... // Import the routing module to find the routing method... const server = http.createServer((req, Const method = req.method const {pathname, query} = url.parse(req.url,true// Process the POST requestif (method === 'POST'// POST requests are divided into data requests and file upload requests. }elseProcessData (method, URL, query, {}, {})} // Public method async for processing request data via routefunctionprocessData(method, pathname, query, post, files) { ... }}) // Listen to the configured port server.listen(HTTP_PORT) // Print the success message of creating the server console.log(' server started at${HTTP_PORT}`)
Copy the code

4. POST requests are classified into data requests and file upload requests

If the content-type of the request header is Application/X-www-form-urlencoded, it means that the request only transmits data and can be directly treated as a string.

If the content-Type of the request header is incorrect, it indicates that the request is an uploaded file and can be processed using multiparty.

// Introduce the module needed to create the server... // Import server configuration... // Import the routing module to find the routing method... const server = http.createServer((req, Const method = req.method const {pathname, query} = url.parse(req.url,true// Process the POST requestif (method === 'POST') {// Depending on the content-Type attribute value of the request header, distinguish between a normal POST request and a file request. // When content-type is Application /x-www-form-urlencoded, normal POST requests are processed directly, file requests are processed with multipartyif (req.headers['content-type'].startsWith('application/x-www-form-urlencoded')) {// Plain POST requestletArr = [] // Store Buffer data // receive data req.on('data', (buffer) => {arr.push(buffer)})'end'. () => {const data = buffer.concat (arr) // Merge received data const post = queryString.parse (data.toString()) // Convert received data to JSON // ProcessData (Method, PathName, Query, POST, {})})}elseForm.parse (req) {// File POST request const form = new form ({uploadDir: HTTP_UPLOAD // specify a file store directory})letPost = {} // Store data parametersletFiles = {} // Store file data // Handle common data form.on('field', (name, value) => {post[name] = value})'file', (name, file) => {files[name] = file})'error', (error) => {console.error(error)})'close'ProcessData (method, pathName, query, POST, files)})}}elseProcessData (method, URL, query, {}, {})} // Public method async for processing request data via routefunctionprocessData(method, pathname, query, post, files) { ... }}) // Listen to the configured port server.listen(HTTP_PORT) // Print the success message of creating the server console.log(' server started at${HTTP_PORT}`)
Copy the code

5. GET requests are divided into data requests and file reading requests, which are distinguished and processed

GET requests can be processed by processData directly. If no data processing method is configured in the route, it indicates that the request is to obtain static files and needs to be processed separately. Otherwise, you only need to call the callback function of the route configuration to process the request.

// Introduce the module needed to create the server... // Import server configuration... // Import the routing module to find the routing method... const server = http.createServer((req, Const method = req.method const {pathname, query} = url.parse(req.url,true// Process the POST requestif (method === 'POST') {... }elseProcessData (method, URL, query, {}, {})} // Public method async for processing request data via routefunctionprocessData(method, pathname, query, post, files) { const callback = findRouter(method, Pathname) // Get the callback function to handle the request // If the callback function exists, it indicates that the route is configured to handle the corresponding data, that is, the request is not to fetch a static file.if(callback) {try {// await callback(res, query, post) Files)} catch (error) {// Error handling res.writehead (500) res.write('Internal Server Error')
        res.end()
      }
    } elseConst filePath = HTTP_ROOT + pathName // Check whether the file exists fs.stat(filePath, (error,stat) = > {ifWriteHead (404) res.write('Not Found')
          res.end()
        } else{// Read the file if it exists // create a readable stream. constreadStream = fs.createreadStream (filePath) // Create a Gzip object to compress the file to const gz = zlib.creategzip () // Send the Gzip compressed file to the browser, set the response header, Otherwise, the browser cannot identify it and automatically downloads it. res.setHeader('content-encoding'.'gzip') // The read content, compressed by gzip, is piped to res. Since RES inherits from Stream, it can also receive piped pushes.readStream.pipe(gz).pipe(res)

          readStream.on('error'. (error) => {console.error(error)})}})}}) // Listen to the configured port server.listen(HTTP_PORT) // Print the success message of creating the server console.log(' server started at${HTTP_PORT}`)
Copy the code

Test server

Introducing a wrapped HTTP module in server.js:

const http = require('./lib/http')
Copy the code

Using the node server. Js to start the server, you can visit http://localhost:8080/index.html in the browser, see the HTML page.