Node.js Foundation: Chapter 3

Keywords: Programming Javascript Attribute Web Server

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

// 1. Import 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 mode

  • 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 demo

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.

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 services

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 the response to the request.

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 routing
  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);
  console.log(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 the 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);
// Results: 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 (() => {});

Using 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) });

Fulfill demand

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 the 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

Fulfill demand

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();

Posted by ctsiow on Sat, 22 Feb 2020 01:43:32 -0800