Node.js Part 3: server programming

Chapter 1: basic concepts of server

1.1 - composition of the website

Web applications are mainly divided into two parts: client and server.

  • Client: the part that runs in the browser is the interface program that the user sees and interacts with. Build using HTML, CSS, JavaScript.
  • Server side: the part running in the server, responsible for storing data and processing application logic.

1.2-Node website server

The machine that can provide website access service is website server, which can receive client's request and respond to the request.

1.3-IP address

Unique identification of the device in the Internet.

IP is the abbreviation of Internet Protocol Address, which represents the Internet Protocol Address.

1.4 - domain name

Because the IP address is hard to remember, the concept of domain name comes into being. The so-called domain name is the web address used for surfing the Internet at ordinary times.

http://www.baidu.com => http://39.156.66.14/

Although the address is entered in the address field, the domain name will eventually be converted to ip to access the specified website server.

1.5-port

The port is the outlet of communication between the computer and the outside world, which is used to distinguish the different services provided by the server computer.

1.6-URL

The Uniform Resource Locator, also known as the Uniform Resource Locator, is a kind of addressing method specially designed to identify the location of resources on the Internet. The webpage address we usually refer to is the URL.

URL composition: Transport Protocol: / / server IP or domain name: port / resource location ID

https://www.baidu.com/index.html

1.7 - client and server during development

In the development phase, the client and server use the same computer, that is, the developer computer.

Local domain name: localhost

Local IP: 127.0.0.1

Chapter 2: creating a web server

If we want to develop back-end programs (server-side), we must have a web server to provide services.

The steps for Node.js to create a server are as follows:

// 1. Import the Node.js system module http module
const http = require("http");
// 2. Create a web server object
const app = http.createServer();
// 3. Register the request event with the server, listen to and respond to user requests
app.on("request", (req, res) => { 
  // Response client
  res.end("Hello!")
});
// 4. Listening port 4000
app.listen(4000);

In local browser: input address → localhost:4000

Chapter 3: HTTP protocol

3.1 - concept

HyperText Transfer Protocol (HTTP) specifies how to transfer hypertext from website server to local browser. It works based on client server architecture and is the standard for client (user) and server (website) requests and responses.

3.2 - message

The data block passed in the process of HTTP request and response is called message, including the data to be transmitted and some additional information, and it should follow the prescribed format.

3.3 - request message

Request method

  • get
  • post

Request address

const http = require("http");
const app = http.createServer();
app.on("request", (req, res) => { 
  // Get request message
  console.log(req.headers);
  // Get the path of the request
  console.log(req.url);
  // How to get the request
  console.log(req.method);
});
app.listen(4000);

3.4 - response message

HTTP status code

200 request succeeded

404 requested resource not found

500 server side error

400 syntax error in client request

Content type

text/html

text/css

application/javascript

image/jpeg

application/json

Code demonstration

const http = require("http");
const app = http.createServer();
app.on("request", (req, res) => { 
  // Set response message (status code and content type and code of response)
  res.writeHead(200, {
    "Content-Type":"text/html;charset=utf-8"
  })
  res.end("<h1>Hello!</h1>");
});
app.listen(4000);

Chapter 4: HTTP request and response processing

4.1 - request parameters

When the client sends a request to the server, sometimes it needs to carry some customer information, which needs to be passed to the server in the form of request parameters, such as query operation, login operation, etc.

https://www.baidu.com/s?wd = is the programmer a monkey?

4.2-GET request parameters

Parameters are placed in the browser address bar, for example: http://localhost:3000/?id=1&type=2

Parameter acquisition needs the help of system module url, which is used to process url address

const http = require("http");
// [import url module]
const url = require("url");
const app = http.createServer();
app.on("request", (req, res) => { 
  // [convert req.url to object, and deconstruct [request path] and [request parameters in object format]]
  let {query,pathname} = url.parse(req.url, true);
  // Request path
  console.log(pathname);
  // Request parameter object
  console.log(query);
});
app.listen(3000);

4.3-POST request parameters

Parameters are placed in the request body for transmission

data event and end event are required to get POST parameters

Using querystring system module to convert parameters to object format

Form:

  <form action="http://localhost:4000" method="POST">
    User name: < input type = "text" name = "username" >
    Password: < input type = "password" name = "PWD" >
    <input type="submit">

  </form>

node service

const http = require("http");
// Import querystring module
const querystring = require("querystring");
const app = http.createServer();
app.on("request", (req, res) => {
  // Define variables, receive client post request parameters
  let paramsStr = "";
  // Register data event receive parameter data
  req.on("data", (chunk) => { paramsStr += chunk });
  // Register end event and handle after receiving
  req.on("end", () => {
    let paramsObj = querystring.parse(paramsStr);
    console.log(paramsObj);
  });

});
app.listen(4000);

4.4 - routing

http://localhost:3000/index

http://localhost:3000/login

Routing refers to the correspondence between the client request address and the server program code. In short, it's about responding to requests.

const http = require("http");
const url = require("url");
const app = http.createServer();
app.on("request", (req, res) => { 
  // Get the path of the request
  let { pathname } = url.parse(req.url, true);
  // Set response header
  res.writeHead(200, { "content-Type": "text/html;charset=utf-8" });
  // Processing routes
  if (pathname == "/index.html" || pathname == "/") {
    res.end("<h1>home page</h1>");
  } else if (pathname == "/list.html") {
    res.end("<h1>List page</h1>");
  } else {
    res.writeHead(404, { "content-Type": "text/html;charset=utf-8" });
    res.end("<h1>Page does not exist</h1>");
  }
  

});
app.listen(4000);

4.5 - static resources

The server does not need to process. The resources that can directly respond to the client are static resources, such as CSS, JavaScript, image files.

https://m.360buyimg.com/babel/jfs/t1/36002/35/9106/3311/5cd4f1bdE06ff07ed/9570fdd46ecd3a76.png

const http = require("http");
const url = require("url");
const path = require("path");
const fs = require("fs");
// Import third-party module mime
const mime = require("mime");

const app = http.createServer();
app.on("request", (req, res) => { 
  // Get the path of the request
  let { pathname } = url.parse(req.url, true);
  // Physical path of files on splicing server
  let realPath = path.join(__dirname, "public", pathname);
  // Get the requested resource type
  let type = mime.getType(realPath);
  // Read server local file
  fs.readFile(realPath, (err, data) => { 
    if (err) {
      res.writeHead(404,{"Content-type":type+";charset=utf-8"});
      res.end("Access resource does not exist");
      return;
    }
    res.writeHead(200);
    res.end(data);
  });
  

});
app.listen(4000);

4.6 - Dynamic Resources

Different response resources with the same request address are dynamic resources.

https://www.baidu.com/s?wd = beauty

https://www.baidu.com/s?wd = handsome guy

4.7 - client request path

  • GET mode
    • Browser address bar
    • The link tag's href attribute
    • src attribute of script tag
    • src attribute of img tag
    • Form form submission
  • POST mode
    • Form form submission

Chapter 5: Node asynchronous programming

5.1 - synchronous API, asynchronous API

Synchronization API: the next API can only be executed after the current API is executed

console.log('before'); 
console.log('after');

Asynchronous API: the execution of current API will not block the execution of subsequent code

console.log('before');
setTimeout(
   () => { console.log('last');
}, 2000);
console.log('after');

Difference 1: difference between synchronous API and asynchronous API (return value):

// [synchronization]
function sum (n1, n2) { 
   return n1 + n2;
} 
const result = sum (10, 20);
// Result: 30

// [asynchronous]
function getMsg () { 
  setTimeout(function () { 
     return { msg: 'Hello Node.js' }
  }, 2000);
}
const msg = getMsg ();
// Result: undefind

Difference 2: difference between synchronous API and asynchronous API (code execution order)

  • The synchronization API executes from top to bottom, and the previous code will block the subsequent code
  • The asynchronous API does not wait for the API to complete before executing the code downward

5.2 - callback function

Basic definition and use of callback function

// getData function definition
 function getData (callback) {}
  // getData function call
 getData (() => {});

Use callback function to get asynchronous API execution result

function getMsg (callback) {
    setTimeout(function () {
        callback ({ msg: 'Hello Node.js' })
    }, 2000);
}
getMsg (function (msg) { 
    console.log(msg);  // Result: Hello Node.js
});

5.3 - asynchronous code execution sequence analysis

console.log('Code execution begins');
setTimeout(() => {
    console.log('2 Code executed in seconds');
}, 2000); 
setTimeout(() => {
    console.log('"0 second"Code executed after');
}, 0);
console.log('Code end execution');

Asynchronous API in 5.4-Node.js

Requirements: read A file, B file and C file in turn

const fs = require("fs");
// Read file 1
fs.readFile("./public/a.txt", "utf-8", function (err, data) {
  console.log(data);
  fs.readFile("./public/b.txt", "utf-8", function (err, data) {
    console.log(data);
    fs.readFile("./public/c.txt", "utf-8", function (err, data) {
      console.log(data);
    })
  })
});

Problem: too many nested callbacks, and the code is not easy to maintain

Solution: Promise object

5.5-Promise object

Basic use

let p1 = new Promise((resolve, reject) => { 
    // resolve indicates the function after successful execution
    // reject represents the function in case of exception
  fs.readFile("./public/1.txt", "utf-8", function (err, data) {
    if (err) {
      reject(err);
    } else {
      resolve(data);
    }
  });
});

p1
  // Operation after successful execution
  .then((data) => { console.log(data) })
  // Action on exception
  .catch((err) => { console.log(err) });

Complete requirements

const fs = require("fs");
function p1() {
  return new Promise((resolve, reject) => {
    fs.readFile("./public/a.txt", "utf-8", (err, data) => { 
      if (err) {
        reject(err);
      } else {
        resolve(data);
      }
    });
  });
}
function p2() {
  return new Promise((resolve, reject) => {
    fs.readFile("./public/b.txt", "utf-8", (err, data) => { 
      if (err) {
        reject(err);
      } else {
        resolve(data);
      }
    });
  });
}
function p3() {
  return new Promise((resolve, reject) => {
    fs.readFile("./public/c.txt", "utf-8", (err, data) => { 
      if (err) {
        reject(err);
      } else {
        resolve(data);
      }
    });
  });
}

p1()
  .then((data) => {
    console.log(data);
    return p2();
  })
  .then((data) => {
    console.log(data);
    return p3();
  })
  .then((data) => {
    console.log(data);
  })

5.6 - asynchronous functions

Asynchronous function is the ultimate solution of asynchronous programming syntax. It allows us to write asynchronous code in synchronous form, so that the code no longer has callback function nesting, and the code becomes clear.

Keyword: async

Syntax: async function fn() {} or const FN = async() = > {};

  1. Add async keyword before the definition of ordinary function ordinary function becomes asynchronous function
  2. Asynchronous function returns promise object by default
  3. Use the return keyword inside the asynchronous function to return results. The result will be returned by the return keyword in the wrapped promise object instead of the resolve method
  4. Using throw keyword to throw program exception inside asynchronous function
  5. Call asynchronous function and then chain call then method to get the execution result of asynchronous function
  6. Call asynchronous function and chain call catch method to get error information of asynchronous function execution
let fn1 = async () => { 
  // throw "abnormal";
  return "success";
};

fn1()
  .then((data) => { console.log(data) })
  .catch((err)=>{console.log(err)})

Keyword: await

  1. The await keyword can only appear in asynchronous functions
  2. await promise await can only be followed by promise object. It is not allowed to write API of other types
  3. The await keyword pauses asynchronous function execution until promise returns the result

Complete requirements

const fs = require("fs");
// It is used to modify the existing asynchronous function api to return promise object, so as to support the syntax of asynchronous function
const promisify = require("util").promisify;
let readFile = promisify(fs.readFile);
async function run() {
  let f1 = await readFile("./public/1.txt", "utf-8");
  let f2 = await readFile("./public/2.txt", "utf-8");
  let f3 = await readFile("./public/3.txt", "utf-8");
  console.log(f1);
  console.log(f2);
  console.log(f3);
}
run();

Chapter 6: extension [optional - learn]

6.1-CommonJS

6.1.1 - what is CommonJs

JavaScript is a powerful object-oriented language with many fast and efficient interpreters. However, JavaScript

The standard defined API is for building browser based applications. There's no one in place for a broader application

Standard library for. The CommonJS specification is proposed to make up for the lack of standard libraries in JavaScript. its

The ultimate goal is to provide a standard library similar to Python, Ruby and Java, rather than just letting JavaScript stop

Stay in the stage of the small script. The application written with CommonJS API can not only use JavaScript developers

Client applications, and you can also write the following applications.

  • Server side JavaScript application. (nodejs)

  • Command line tools.

  • Desktop GUI application.

CommonJS * * is the standard of modularity, * * nodejs is the implementation of CommonJS (modularity)

6.1.2-CommonJS specification

  • require('module name ') import module
  • module.exports or exports export module content

6.2-npm correlation

6.2.1-npm introduction

npm is the largest open source ecosystem in the world. We can download all kinds of packages through npm,

These source code (packages) we can https://www.npmjs.com Found.

npm is a package management tool installed with NodeJS, which can solve many problems in NodeJS code deployment,

Common usage scenarios are as follows:

  • Allows users to download third-party packages written by others from the NPM server for local use. (silly-datetime)

  • Allows users to download and install command-line programs (tools) written by others from NPM server for local use. (supervisor)

  • Allow users to upload their own packages or command-line programs to NPM server for others to use

6.2.2-npm command

npm -v view npm version

npm -v

Using npm command to install module

npm install Module Name

For example, install jq module: npm install jquery

Specify the version to install npm install jquery@1.8.0

npm uninstall moudleName uninstall module

For example, uninstall jq module: npm uninstall jquery

npm list to view the installed node packages in the current directory

npm list

npm info moduleName view module system information

For example: npm info jquery view the version of jquery

6.3-fs module common API

6.3.1-fs.stat get file information

const fs = require('fs')
// Detect a local file
fs.stat('./data/hello.js', (err, stats) => {
  if (err) {
    // If there is an exception in reading the local file, the exception information will be printed
    console.log(err.message)
  } else {
    console.log(stats)
    console.log('Is it a file' + stats.isFile())
    console.log('Is it a folder' + stats.isDirectory())
    // Unit is b-bit
    console.log('size:' + Math.ceil(stats.size/1024) + 'kb')
  }
})

Output results:

Is it a file: true
 Is it a folder: false
 Size: 85kb

6.3.2-fs.mkdir create directory

// Create a logs directory under the data directory
fs.mkdir('./data/logs', (error) => {
  if (error) {
    console.log(error)
  } else {
    console.log('Directory created successfully: logs')
  }
})

6.3.3-fs.writeFile write file

fs.writeFile('./data/logs/hello.log', 'Hello! ~ \n', (error) => {
  if (error) {
    console.log(error)
  } else {
    console.log('File written successfully')
  }
})

6.3.4-fs.appendFile append file

fs.appendFile('./data/logs/hello.log', 'Hello! ~ \n', (error) => {
  if (error) {
    console.log(error)
  } else {
    console.log('Append write file')
  }
})

6.3.5-fs.readFile read file

fs.readFile('./data/logs/hello.log', 'utf8', (error, data) => {
  if (error) {
    console.log(error)
  } else {
    console.log(data)
  }
})

6.3.6 - read directory

fs.readdir('./data', (error, files) => {
  if (error) {
    console.log(error)
  } else {
    console.log(files)
    // [ 'hello.js', 'logs', 'test01.js' ]
  }
})

6.3.7 - Rename

const fs = require('fs')
// fs.rename(oldName,newName,callback)
fs.rename('./data/test01.js', './data/test02.js', (err)=>{
  if (err) {
    return err.message
  } else {
    console.log('Rename succeeded!')
  }
})

6.3.8 - delete files

const fs = require('fs')
fs.unlink('./data/logs/log.js', (err) => {
  if (err) return err
  console.log('Delete successfully!')
})

6.3.9 - read data from file stream

const fs = require('fs')
const fileStream = fs.createReadStream('./data/hello.js')
var count = 0
var str = ''
fileStream.on('data', (chunk) => {
  console.log(chunk.toString())
  str += chunk
  count++
})
fileStream.on('end', (chunk) => {
  cosnole.log('Read end')
  console.log(str)
})
fileStream.on('error', (err) => {
  console.log(err)
})

6.3.10 - write data to stream

var fs = require("fs");
var data = 'I got the data from the database. I want to save it';
//Create a writable stream and write it to the file output.txt
var writerStream = fs.createWriteStream('output.txt');
//Write data using utf8 encoding
writerStream.write(data, 'UTF8');
//Mark end of file
writerStream.end();
// Process flow event -- > finish eventfinish - triggered when all data has been written to the underlying system.
writerStream.on('finish', function () { 
  console.log('Write complete')
})
writerStream.on('error', function (err) { 
  console.log(err)
})

6.3.11 - pipe flow

The pipeline provides a mechanism for output flow to input flow. Usually we are used to get data from one flow and pass it to another.

As shown in the above picture, we compare the file to a bucket of water, and water is the content of the file. We use a pipe to connect two buckets so that water flows from one bucket to another, so that we slowly realize the copying process of large files.

In the following example, we read the contents of one file and write them to another file.

var fs = require("fs");
// Create a readable stream
var readerStream = fs.createReadStream('./data/hello.js');
// Create a writable stream
var writerStream = fs.createWriteStream('output.txt');
// Pipeline read / write operation 
// Read the contents of the input.txt file and write the contents to the output.txt file
readerStream.pipe(writerStream);
console.log("Program execution completed");

Tags: Programming npm Javascript JQuery Web Server

Posted on Mon, 11 May 2020 09:51:55 -0400 by warik