What is Nodejs

Nodejs is a V8-engine based runtime environment

1. Use the Node management tool

Node version management tool: n(not supporting Windows), nvM-Windows

  • NVM list: Check which node versions are available on your computer
  • NVM install 14.13.1 Installs the specified version
  • NVM install LTS Installs the LTS
  • nvm list available
  • NVM Use Version: Switch to the corresponding version
  • NVM Uninstall Version number: uninstalls the corresponding version

2. The REPL Node

  • REPL is short for read-eval-print Loop, which translates as “read-eval-print Loop”.
  • Is a simple, interactive programming environment for executing code in the Node environment

JS modularity and Node modularity

// Clear the console
console.clear()

// Print the call stack of the function
console.trance()
Copy the code

1.commonJs

Node implements CommonJS as reference assignments to objects (shallow copies)

/ / export
exports.name = name

/ / introduction
const { name } = require('/ path')
Copy the code

An export is essentially a Module. Export export. Once a Module. Expor export is an export, expor exports will not work

Node internally does one thing for us: module.export = export

Module. Export = {}; / / export = {}; / / export = {}

The core module of require

1. Search order for files without suffix:

  1. Go straight to file X
  2. Find X.j s
  3. Find X.j son
  4. Find X.n ode

2. No corresponding file is found

Look for the index file in the directory

  1. Go directly to the file X/index.js
  2. Find the X/index. Js
  3. Find the X/index. Json
  4. Find Xindex. Node

Commonjs in Node is synchronized with the loading process

require('./index.js')

console.log('Main's code is executed') // Execute the file index.js first and then execute the code in mian
Copy the code

2.ESmodule

Introducing a JS file into an HTML file does not treat it as a module; you must add type=module to make it a module

<body>
    <script src="./index.js" type="module"></script>
</body>
Copy the code

There are three export methods:

  1. Method 1: Add export before a method or variable

    export const name = 'Ming'
    
    export const function sayHello(msg) {
        console.log(msg)
    }
    Copy the code
  2. Method 2: export(not an object)

    export {
    	name,
        sayHello
    }
    Copy the code
  3. Export aliases variables when exporting

    export {
    	name as fName,
        sayHello as fSayHello
    }
    Copy the code

There are three common import methods

  1. Import {} from ‘./ path.js’

    import { name } from '/ path. Js'   //.js cannot be omitted
    Copy the code
  2. Alias the exported variable

    import { name as wNamme } from '/ path. Js'
    
    // Export with the alias fName
    import { fName as wNamme } from '/ path. Js'
    Copy the code
  3. By * as foo

    import * as foo from '/ path. Js'
    
    console.log(foo.name)
    Copy the code

Use export and Import together (Understand)

export { name, age} form './xxx.js'
Copy the code

Default export (there can only be one default export in a modularity)

export default function () {
    console.log('Default export')}/ / introduction
importAny name form'./xxx.js'
Copy the code

The EsModule loading process is asynchronous

Run the ES module with the.mjs file suffix

CommonJS and ES Module interactions:

  • Normally CommonJS cannot load the EsModule
  • In most cases, the ESModule can load CommonJS

3. Common built-in modules in Node

1. Path module (splicing path)

const path = require('path')

const basePath = '/User'
const fileName = '/abc.txt'

// Splice paths
const filePath = path.reslove(basePath, fileName)
Copy the code

Path module method:

  1. Obtaining Path Information

    const filepath = '/User/yogln/abc.txt'
    
    // Obtain the path
    path.dirname(filepath)
    // Get the file name
    path.basename(filepath)
    // Get the file name extension
    path.extname(filepath)
    Copy the code
  2. Join path Splicing

    const path = path.join(basePath, fileName)
    Copy the code
  3. Resolve path splicing

    const filePath = path.reslove(basePath, fileName) 
    Copy the code

    The difference between:

    Reslove determines if the concatenated string path is preceded by/or./ or.. Paths beginning with /,

    If there is a relative path to the current location of the path into the splicing

    A join will only concatenate strings that begin with /

2. Fs module (file system)

1. Fs Three operations for obtaining file information

// Read the file abc.txt hello worldCopy the code
const fs = require('fs')
const filepath = './abc.txt'

// 1. Method 1: Synchronize the operation. Subsequent code to be executed will be blocked
const info = fs.ststSync(filepath)
console.log(info)            

// 2. Mode 2: Asynchronous mode
fs.stat(filepath, (err, info) = > {
    if(err) {
        console.log(err)
        return
    }
    console.log(info)
})

// 3
fs.promises.stat(filepath).then(info= > {
    console.log(info)
}).catch(err= > {
    console.log(err)
})
Copy the code

2. File descriptors

const fs = require('fs')
fs.open('./abc.txt'.(err, fd) = > {
    if(err) {
        return
    }
   // Print the file descriptor
  	console.log(fd)  
   // Obtain the file information from the file descriptor
    fs.fstat(fd, (err, info) = > {
        console.log(info)
    })
})
Copy the code

3. Read and write files

Write files
const fs = require('fs')

const content = 'Hello, Li Yinhe.'

fs.writeFile('./abc.txt', content, err= > {
  console.log(err)
})
Copy the code

Flag options

W Open file write, default value;

W + Open the file for reading and writing. If no file exists, create the file.

R Open the file for reading, the default value for reading;

R + opens the file for reading and writing, and throws an exception if it doesn’t exist;

A opens the file to be written, and banishes it at the end of the file. If it does not exist, create the file.

A + opens the file for reading and writing and is banished at the end of the file. If it does not exist, create the file

// Append to the end of the file
fs.writeFile('./abc.txt', content, {flag: "a"}, err= > {
  console.log(err)
})
Copy the code

Encoding selection, default UTF-8

If encoding is not specified, Buffer is returned.

4. Read files

fs.readFile('./abc.txt', {encoding: 'utf-8'}, (err, data) = > {
  console.log(data);
})
Copy the code

5. Folder operations

const fs = require('fs')

// 1. Create folders
const dirname = './yogln'
if(! fs.existsSync(dirname)) { fs.mkdir(dirname,err= > {
    console.log(err)
  })
}
// 2. Read all files in the folder
fs.readdir(dirname, (err, files) = > {
  console.log(files); // Output: ['test.txt']
})

// 3. Rename the folder
fs.rename('./yogln'.'newName'.err= > {
  console.log(err);
})
Copy the code

Extension: recursively read the contents of the file {withFileTypes: true} to get the type of the folder (object)

function getFiles (dirname) {
  fs.readdir(dirname, { withFileTypes: true }, (err, files) = > {
    for (let file of files) {
      if(file.isDirectory()) {
        const filePath = path.reslove(dirname, file.name)
        getFiles(filePath)
      }else{
        console.log(file.name); }}})}Copy the code

3. The events module

const EventEmitter = require('events')

// 1. Create an emitter
const emitter = new EventEmitter()

// 2. Listen for an event
// on alisa addListerner
emitter.on('click'.args= > {
  console.log('Click event heard', args);
})

// 3. Send an event
emitter.emit('click'.'yogln')


// Print the result
// Listen to the click event yogln
Copy the code

Cancel to monitor

const listener2 = args= > {
  console.log('Click event heard', args);
}

emitter.off('click',listener2 )
Copy the code

Other methods rarely used

emitter.eventsNames() // Which methods to get registered

// Listen only once
emitter.once('click'.args= > {
  console.log('Click event heard', args);
})

// Put the listen first
emitter.prependListener('click'.args= > {
  console.log('Click event heard', args);
})

// Remove all listeners
emitter.removeAllListener()
// Remove a single listener
emitter.removeAllListener('click')
Copy the code

4. NPM package management

Script:

What is the difference between NPM start and NPM Run start?

  • They’re equivalent;
  • For common start, test, stop, and restart, you can skip run and run them directly in NPM start mode.

Semver version specification

The semver version specification is X.Y.Z:

  • X major: When you make an API change that is incompatible (possibly incompatible with previous versions);
  • Minor: When you do backward compatible functionality (new features are added, but are compatible with previous releases);
  • Z Fix (patch) : When you fix backwards compatibility issues (no new features, fixed bugs in previous versions)

Here’s the difference between ^ and ~ :

^ X.Y.Z: x is unchanged, y and z are always installed with the latest version;

~ X.Y.Z: x and y remain the same. Z always installs the latest version.

Create your own scaffolding tools

1. Run the xyl command to execute the entry file index.js

Create the corresponding project with the ·index.js entry file

#! /usr/bin/env node
console.log('xyl cli')
Copy the code

Run NPM init -y to initialize a package.json file and configure it inside

"bin": {
    "xyl": "index.js"
  },
// Xyl is the command
// index.js specifies the file to execute
Copy the code

Do not skip this step, run the NPM link command, our command into a link

Then enter xyl in the terminal to execute the corresponding index file

2. Run the xyl –version command to view the version number

Download Commander first in your project

npm install commander

#! /usr/bin/env node
const program = require('commander')
// To get the version number, require the package.json object
program.version(require('./package.json').version)


// Parse the command we entered through the arguments of the process process
program.parse(process.args)
Copy the code

The xyl –version command displays the version number. The xyl — help command defaults

3. Other options

// Add your own options
program.option('-x --xyl'.'a xyl cli')
program.option('-d --dest <dest>'.'a destination floder, for example: -d/ SRC /components')
/ / to monitor
program.on('--help'.() = > {
  console.log("Other: ")
  console.log(" other options~")})Copy the code

4. Run the create command to create the project

Create new js

const program = require('commander')

const  creatCommand =() = > {

  program
    .command('create 
      
        [others...] '
      ) / / command
    .description('clone repository into a floder') / / description
    .action((project, others) = > { / / action
      console.log(project, others)
    })

}
module.exports = creatCommand
Copy the code

Called in index.js

const program = require('commander')
// Create other directives
creatCommand()
Copy the code

5. Develop your own scaffolding tool (project folder 06 learnCli)

// Convert the callback function to a promise
const { promisify } = require('util')

const download = promisify(require('download-git-repo'))
const open = require('open')

const { vurRepo } = require('.. /config/repo-config')
const { commandSpawn } = require('.. /utils/terminal')
const createProjetActions = async (project) => {
  // Wait too long, print the dot information
  console.log('xyl helps you creat project')
  / / 1. Clone project
  await download(vurRepo, project, { clone: true })
  // 2. Run NPM install
  const command = process.platform === 'win32' ? 'npm.cmd' : 'npm'
  await commandSpawn(command, ['install'] and {cwd: `. /${project}` })
  // 3. Run NPM Run Serve
  // Prevent blocking Step 4 open the browser 8080 occupy blocking
  commandSpawn(command, ['run'.'serve'] and {cwd: `. /${project}` })
  // 4. Open the browser
    // 4.1 npm install open
  open('http://localhost:8080/')}module.exports = {
  createProjetActions
}
Copy the code

I didn’t learn the latter because it was a little difficult to understand

6. Post your own scaffolding

  1. Register on the NPM website

  2. Enter the command on the terminal

    npm login

  3. Modify package.json,keywords,license, repository, etc

    "repository": {
        "type": "git"."url": "Warehouse address"
    }
    Copy the code
  4. Perform NPM Publish

    npm publish

Six, Buffer

1. Buffer encoding and decoding

const msg = 'Hello World'

/ / create a buffer
const buffer = new Buffer.from(msg)
console.log(buffer)

// A Chinese language occupies 3 bytes
const msg2 = 'hello'
// const buffer2 = new Buffer.from(msg2)
// console.log(buffer.length);  // 6 
const buffer2 = new Buffer.from(msg2, 'utf16le')
console.log(buffer2.length); / / 2
// utf16l A Chinese character occupies two codes

/ / decoding
console.log(buffer2.toString('utf16le'))
Copy the code

2. Alloc creation mode of buffer

/ / by
const buffer = Buffer.alloc(8)
console.log(buffer)

/ / modify buffer
buffer[0] = 88
// In js, starting with 0x indicates hexadecimal
buffer[1] = 0x88
console.log(buffer)
Copy the code

3. Operation of buffer files

A. Read the text

const fs = require('fs')

// Do not add {encoding: 'utF-8 '},
fs.readFile('./foo.txt'.(err, data) = > {
  console.log(data)
  console.log(data.toString())
})
Copy the code

B. Read the picture

const fs = require('fs')

fs.readFile('./captain.jpg'.(err, data) = > {
  console.log(data)
  fs.writeFile('./foo.jpg', data, err= > { // Write the picture
    console.log(err)
  })
})
Copy the code

C. Use Sharp to manipulate the image

Install the Sharp library and operate on the image

npm install sharp

Methods a

const sharp = require('sharp')

sharp('./captain.jpg')
  .resize(200.200)
  .toFile('./baz.jpg')
Copy the code

A new 200 x 200 baz.jpg image will be generated

Way 2

sharp('./captain.jpg')
  .resize(200.200)
  .toBuffer()
  .then( data= > {
    fs.writeFile('./bax.jpg', data, err= > console.log(err))
})
Copy the code

Event loops and asynchronous IO

What is an event loop?

The event loop is a bridge between JavaScript and the browser or Node

  • Process: a program that is already running on a computer
  • Thread: The smallest unit in which an operating system can run a schedule

1. Browser event loop

Queue of event loops

  • Macro task queue: Ajax, setTimeOut, setInterval, DOM listener, UIRendering, etc
  • Microtask queues: Then call-back for promises, MutaionObserver API, quenceMicrotask(), and so on

Execution order

  1. Execute script code first
  2. Execute the microtask queue
  3. The macro task queue is executed only after all microtask queues have been executed

2. Blocking and non-blocking IO

  • The operating system provides us with blocking and non-blocking calls:
    • Blocking: The current thread is blocked until the result of the call is returned. (Blocked CPU does not allocate time slices.) The calling thread will not continue execution until the result of the call is received.
    • Non-blocking call: after the call is executed, the current thread does not stop executing, only after a period of time to check if any results have been returned.

3. What’s the difference between blocking and non-blocking, synchronous and asynchronous?

Blocking and non-blocking are for the caller

  • In our case, system calls, the operating system provides us with both blocking and non-blocking calls;

Synchronization and asynchrony are for the caller;

  • In our case it’s our own program;
  • If we do nothing but wait for the result after the call is made, the process is called synchronous;
  • If we make another call, do not wait for the result, continue to complete other work, wait until there is a callback to execute, this process is asynchronous call;

Libuv uses non-blocking asynchronous IO calls

4. Event loops in Node

The event loop continues to retrieve events (callbacks) from the task queue for execution

But a complete event loop ticks into many phases:

  • Timers: This phase executes the callback functions that have been set by setTimeout() and setInterval().
  • Pending Callback: Executes a Callback for some system operation (such as TCP error type), such as ECONNREFUSED when a TCP connection is received.
  • Idle, prepare: Used only in the system.
  • Poll: Retrieve new I/O events. Perform I/ O-related callbacks;
  • Detect: setImmediate() the callback function executes here. P closed callback: some closed callback functions, such as: socket.on(‘close’,…) .

Microtasks and macro tasks in Node

We can see that Node’s event loop is more complex in terms of the Tick of an event loop, which is also divided into microtasks and macro tasks:

  • Macrotask: setTimeout, setInterval, IO event, setImmediate, close event;
  • Microtask: Promise then callback, process. NextTick, queueMicrotask;

Execution order

  1. Next Ticks queue: process. NextTick;
  2. Other microtask queues: THEN callbacks for promises, queueMicrotask
  3. Timers queue: setTimeout and setInterval
  4. IO queue: IO events
  5. Check queue :setImmediate
  6. Close queue: indicates the close event

Think: setTimeout and setImmediate perform order analysis **

** Case 1: setTimeout, setImmediate **

Scenario 2: setImmediate, setTimeout Why?

Why is it different?

  • In the Node source deps/uv/ SRC /timer.c line 141, there is a function uv__next_timeout
  • This function determines whether or not the poll phase should block here;
  • The purpose of blocking here is to get the code to execute as quickly as possible when there is asynchronous I/O being processed;

What does it have to do with that?

Case 1: if the event loop is enabled for a time (ms) less than the execution time of setTimeout;

  • This means that event-loop is started first, but the execution reaches the timer phase, and no timer callback is put into the timer queue.
  • If the timer is enabled or “setImmediate” is detected, the poll phase is skipped and the execution progresses backward.
  • At this time, setImmediate is detected first, and setTimeout in the timer is executed in the second tick.

Case 2: if the event loop is enabled for a time (ms) greater than the execution time of the setTimeout function;

  • This means that on the first tick, the timer queue is ready;
  • So I’m just going to do it in sequence

Eight, the Stream

1. Read a file from a stream (createReadStream)

const fs = require('fs')
// Use stream mode to read accurately
const reader = fs.createReadStream('./foo.txt', {
  start: 3.end: 6.highWaterMark: 2 // indicates how much to read each time
})
// Listen for read data
reader.on('data'.data= > {
  console.log(data)
})
Copy the code

Supplement:

reader.on('open'.() = > {
  console.log('File opened')
})
reader.on('close'.() = > {
  console.log('File closed')})Copy the code

Pause and resume

reader.pause()

reader.resume()
Copy the code

2. Write to file via Stream (createWriteStream)

const fs = require('fs')

const writer = fs.createWriteStream('./bar.txt', {
  flags: 'a'.// Win system 'r+' can be implemented
  start: 4
})

writer.write('Hello'.err= > {
  if (err) {
    console.log(err)
  }
  console.log('Write successful')})Copy the code

File closing

// writer.close()
writer.end('hello srteam')
// end closes the file while writing
writer.on('close'.() = > {
  console.log('File closed')})Copy the code

3. Read and write files (PIPE)

const fs = require('fs')

const reader = fs.createReadStream('./foo.txt')
const writer = fs.createWriteStream('./foz.txt')

reader.pipe(writer)
writer.close()
Copy the code

Nine, HTTP

1. HTTP development Web server

const http = require('http')

// Create a Web server
const server = http.createServer((req,res) = > {
  res.end('hello server')})// Start the server (port 0-65535, host,)
server.listen(8000.'0.0.0.0'.() = >{
  console.log('Server started successfully')})Copy the code

To enable the server to restart automatically after each code change, install nodemon

npm install -g nodemon

Start the server using Nodemon

nodemon index.js

2. Method for creating a server

/ / way
const server = http.createServer((req,res) = > {
  res.end('hello server')})2 / / way
const server = new http.Server((req,res) = > {
  res.end('hello server')})Copy the code

The essence of creating a server is the same in both cases

3. Listen to the host and port number

The listen method is used to enable the Server to listen for network requests on a host and port:

  • That is, when we send the IP :port to the Web server we are listening to
  • We can do something about it

The listen function takes three arguments:

  • Port port: can not be transmitted, the system will default to the allocation end, we will write to the environment variable in the subsequent projects;

  • Host: You can usually pass in localhost, IP address 127.0.0.1, or IP address 0.0.0.0. The default is 0.0.0.0.

    • Localhost: essentially a domain name, normally resolved to 127.0.0.1;
    • 127.0.0.1: Loop Back Address, which means that the packets sent by our host are directly received by ourselves.
      • Normal database packets are usually applied layer – transport layer – network layer – data link layer – physical layer.
      • The loopback address, which is obtained directly at the network layer, is not often accessed at the data link layer and physical layer;
      • For example, when we listen to 127.0.0.1, in the same network segment of the host, through the IP address is not accessible;
    • 0.0.0.0:
      • Listen for all IPV4 addresses and find different applications based on the port;
      • For example, if we listen for 0.0.0.0, the host in the same network segment can be accessed through the IP address
  • Callback function: the callback function when the server starts successfully

4. The request object

A.r equest object url

const http = require('http')
const url = require('url')
const qs = require('querystring')

// Create a Web server
const server = http.createServer((req, res) = > {
  // 1. The request object is installed with all the information sent by the client to the server

  if (req.url === '/login') {
    res.end('Welcome to login')}else if (req.url === '/home') {
    res.end('Welcome back')}else {
    res.end('404 error request ')}// Parse urls by QS
  const {pathname, query } = url.parse(req.url)
  if(pathname === '/login') {
    console.log(query)
    console.log(qs.parse(query))
    const { username, password } = qs.parse(query)
    console.log(username, password)
  }
})

// Start the server (port 0-65535, host,)
server.listen(8000.'0.0.0.0'.() = > {
  console.log('Server started successfully')})Copy the code

Send the request

http://localhost:8000/login?username=aa&&password=123

Print result:

username=aa&&password=123
[Object: null prototype] { username: 'aa', password: '123' }
aa 123
Copy the code

B. Requset Object method, which gets the body content of the POST method

const http = require('http')
const url = require('url')
const qs = require('querystring')

// Create a Web server
const server = http.createServer((req, res) = > {
  const { pathname } = url.parse(req.url)
  if (pathname === '/login') {
    if (req.method === 'POST') {
      req.setEncoding('utf-8')
      req.on('data'.data= > {
        const { username, password } = JSON.parse(data) // Turn the string into an object
        console.log(username, password)
      })
    }
  }
  res.end('hello server')})Copy the code

5. The response object

A.esponse Response object

const http = require('http')

// Create a Web server
const server = http.createServer((req,res) = > {
  // Response result
  res.write('Response result')
  res.end()
})
Copy the code

B. a status code

1. Request status code
const server = http.createServer((req,res) = > {
  // Set the status code
  // Method 1: assign values to attributes directly
  res.statusCode = 400
  // Method 2: set with head
  res.writeHead(503)})Copy the code
2. Response status code
const server = http.createServer((req,res) = > {
  // Set the response header
  res.setHeader("Content-type"."text/plain; charset=utf-8")
  res.writeHead(200, {
    "Content-type": "text/plain; charset=utf-8"
  })
  res.write('Response result')})Copy the code

C. HTP sends a network request

A get request

const http = require('http')

http.get('http://localhost:8000/login'.res= > {
  res.on('data'.data= > [
    console.log(data.toString())
  ])

  res.on('end'.() = > {
    console.log('Got all the results.')})})Copy the code

For other methods, modify method only

const req = http.request({
  method: 'POST'.hostname: 'localhost'.port: 8000
}, res= > {
  res.on('data'.data= > [
    console.log(data.toString())
  ])

  res.on('end'.() = > {
    console.log('Got all the results.')})})Copy the code

6. Upload files

Native file upload is too troublesome, real projects use the framework, here no longer……

10. Expresss Framework

1. Install

Scaffold installation:

npm install -g express-generator

Create a project through Express

Express the project name

Install dependencies

npm install

Run the project

node bin/www

2. The early experience

const express = require('express')

// Express is a function: createApplication
/ / return the app
const app = express()

// Listen for the default path
app.get('/'.(req, res, next) = > {
  res.end('hello express')
})
app.post('/login'.(req, res, next) = > {
  res.end('Welcome to login')})// Enable listening
app.listen(8000.() = > {
  console.log('Express started successfully')})Copy the code

Send the request and the corresponding request path to return the corresponding result

3. The middleware

A. The most common middleware

When registering multiple common middleware, by default only the first one corresponds, and only the next middleware is called with next()

const express = require('express')

const app = express()

// Write common middleware
// Register a middleware in the use mode
app.use((req, res, next) = > {
  console.log('Register a generic middleware 01')
  res.end('End request')
  next()
})
app.use((req, res, next) = > {
  console.log('Register a common middleware 02')
  // res.end(' end request ') // An error will be reported if this is written, because the middleware above has already terminated the response
  next()
})

app.listen(8000.(req, res, next) = > {
  console.log('Common middleware')})Copy the code

B. Path matching middleware

Path matches middleware, only path does not match method, multiple middleware also need next execution

const express = require('express')

const app = express()
// app.use(path, cb)
app.use('/home'.(req, res, next) = > {
  console.log('Home 01')
  res.end('home middleware')
  next()
})
app.use('/home'.(req, res, next) = > {
  console.log('Home 02')
}) 


app.listen(8000.(req, res, next) = > {
  console.log('Path matching middleware server started successfully ~')})Copy the code

C. Paths and methods match the middleware

Matches both paths and methods

const express = require('express')

const app = express()

// Paths and methods match the middleware
app.get('/home'.(req, res, next) = > {
  console.log('home path')
  res.end()
})
app.post('/login'.(req, res, next) = > {
  console.log('login path')
  res.end()
})

app.listen(8000.() = > {
  console.log('Path and method middleware server started successfully ~')})Copy the code

D. Continuously register middleware

It also requires next() to execute the next piece of middleware

const express = require('express')

const app = express()

app.use((req, res, next) = > {
  console.log('Common middleware')
  next()
})
app.get('/home'.(req, res, next) = > {
  console.log('Continuous registration of middleware 01')
  next()
}, (req, res, next) = > {
  console.log('Continuous registration of middleware 02')
  next()
}, (req, res, next) = > {
  console.log('Continuous registration of middleware 03')
  res.end('home page')
})

app.listen(8000.() = > {
  console.log('Continuous registration of middleware server started successfully ~')})Copy the code

4. Body parameter parsing of middleware applications (large project plug-in: Body-Parse)

Write your own body parsing

const express = require('express')

const app = express()

app.use((req, res, next) = > {
  if (req.headers["content-type"= = ='application/json') {
    req.on('data'.data= > {
      const info = JSON.parse(data.toString())
      req.body = info
    })
    req.on('end'.() = > {
      next()
    })
  } else {
    / / not parsing
    next()
  }
})

app.post('/login'.(req, res, next) = > {
  console.log(req.body)
  res.end('Login successful ~')
})

app.post('/products'.(req, res, next) = > {
  console.log(req.body)
  res.end('Upload item successfully ~')
})

app.listen(8000.() = > {
  console.log('Server started successfully ~')})Copy the code

You can parse the value when it is passed through the body JSON. The following method is simpler

const express = require('express')

const app = express()

app.use(express.json()) // Parse the json format directly

app.post('/login'.(req, res, next) = > {
  console.log(req.body)
  res.end('Login successful ~')
})

app.post('/products'.(req, res, next) = > {
  console.log(req.body)
  res.end('Upload item successfully ~')
})

app.listen(8000.() = > {
  console.log('Server started successfully ~')})Copy the code

What if it’s some other way of passing values? For example, form transmission value: urlencoded

app.use(express.urlencoded({ extended: true}))
// Extended: Trued parsed Urlencoded using a third-party library QS
// Extended: false Parsed Urlencoded using the node built-in queryString module
Copy the code

5. Analysis of middleware application formdata

Express’s own parsing tool cannot help us with parsing. We need to download the third-party tool Multer

npm install multer

const express = require('express')
const multer = require('multer')

const app = express()
const upload = multer()

app.use(upload.any())
app.post('/login'.(req, res, next) = > {
  console.log(req.body)
  console.log('Login successful')
})
app.listen(8000.() = > {
  console.log('Server started successfully ~')})Copy the code

6. Upload the form-data file

const path = require('path')
const express = require('express')
const multer = require('multer')

const app = express()
const storage = multer.diskStorage({
  destination: (req, file, cb) = > {
    cb(null.'./uploads/',)},filename: (req, file, cb) = > {
    cb(null.Date.now() + path.extname(file.originalname))
      // Get the timestamp and the suffix of the original file}})const upload = multer({
  // dest: './uploads/'
  storage
})

app.post('/login', app.use(upload.any()), (req, res, next) = > {
  console.log(req.body)
  console.log('Login successful') 
})

app.post('/upload', upload.single('file'), (req, res, next) = > {
  console.log(req.files)
  res.end('File uploaded successfully')
})

app.listen(8000.() = > {
  console.log('Server started successfully ~')})Copy the code

App.use (upload.any()) cannot be used globally

7. The middleware generates logs

First install the third-party log library: Morgan

npm install morgan

const express = require('express')
const morgan = require('morgan')
const fs = require('fs')

const app = express()
const writerStream = fs.createWriteStream('./logs/access.log', {
  flags: 'a+'
})

// combined: a format for printing logs
// {stream: writerStream} : where to save logs
app.use(morgan('combined', { stream: writerStream }))

app.get('/home'.(req, res, next) = > {
  res.end('hello world')
})

app.listen(8000.() = > {
  console.log('Server started successfully')})Copy the code

8. Request parameter parsing

params

const express = require('express')

const app = express()

app.get('/products/:id'.(req, res, next) = > {
  console.log(req.params)
  // console.log(req.query)
  res.end('Commodity details')
})

app.listen(8000.() = > {
  console.log('Server started successfully')})Copy the code

9. Response data

const express = require('express')
const app = express()

app.get('/login'.(req, res, next) = > {
  // Return the data in method 1:
  // res.type('applicaton/json') // Set the return format to JSON
  // res.end(JSON.stringify({name: 'xyl', age: 18}))
  // return data to method 2 :(most used in development)
  res.json({name: 'xyl'.age: 18})
  // Return the status and respond to the status code
  res.statusCode(204)
})
app.listen(8000.() = > {
  console.log('Server started successfully')})Copy the code

10. Route usage

/routers/user.js

const express = require('express')

const router = express.Router()

router.get('/users'.(req, res, next) = > {
  res.json(['xyl'.'kobe'.'why'])
})
router.post('/users'.(req, res, next) = > {
  res.json('create user success')
}) 
router.get('/users/:id'.(req, res, next) = > {
  res.json(`${req.params.id}User information ')})module.exports = router 

Copy the code
const express = require('express')
const userRouter = require('./routers/user')

const app = express()
app.use("/", userRouter)


app.listen(8000.() = > {
  console.log('Server started successfully')})Copy the code

11. Deployment of static projects

app.use(express.static('./ project path '))
Copy the code

11. Koa Framework

1. At the beginning of koa experience

Installation of koa

npm init -y

npm install koa

const Koa = require('koa')

const app = new Koa()

app.use((ctx, next) = > {
  console.log('Middleware being executed')
  // Return the result
  ctx.response.body = "I am the result returned."
})

app.listen(8000.() = > {
  console.log('KOA server started successfully')})Copy the code

Note:

  • Koa middleware can only be registered through use, and app.use(‘/login’, ()) is not provided
  • No app.get,app.post, etc
  • There is also no way to continuously register middleware

2. Use of routes in KOA

Installing third-party libraries

npm install koa-router

routers/user.js

const Router = require('koa-router')

const router = new Router({prefix: '/users'})

router.get('/'.(ctx, next) = > {
  ctx.response.body = 'get request'
})
router.put('/'.(ctx, next) = > {
  ctx.response.body = 'put request'
})

module.exports = router
Copy the code
const Koa = require('koa')
const userRouter = require('./routers/user')
const app = new Koa()

app.use((ctx, next) = > {
 next()
})
app.use(userRouter.routes())
// When a method is not implemented, it will indicate that the method is not implemented
app.use(userRouter.allowedMethods())
app.listen(8000.() = > {
  console.log('Server started successfully')})Copy the code

Params and Query parameter parsing in KOA

The difference between params and Query in KOA:

  • App.get (“/deleteUser/:id”, function(req, res) {… });

  • The requested URL: http://localhost:8080/deleteUser/2? User = zhang SAN & passwd = zhangsan

  • Page results:

    req.params: {
    	"id": "2"
    }
    req.query: {	
        "user": "Zhang"."passwd": "zhangsan"
    }
    Copy the code

Req. Params is a query parameter pair. Req.query is the part of the back-end code that corresponds to: name.

const Koa = require('koa')
const Router = require('koa-router')
const userRouter = new Router({prefix: '/users'})

userRouter.get('/:id'.(ctx, next) = > {
  console.log(ctx.request.params)
  console.log(ctx.request.query)
})
const app = new Koa()

app.use(userRouter.routes())
app.listen(8000.() = > {
  console.log('Server started successfully')}){id: 'ABC'} [Object: null prototype] {name: 'xyl', age: '18'} */
Copy the code

Enter the request localhost:8000/users/ ABC? name=xyl&age=18

4. Json and Urlencoded parsing in KOA

Installing third-party libraries

npm install koa-bodyparser

The json value of the data in the POST request is passed

const Koa = require('koa')
const bodyParser = require('koa-bodyparser')
const app = new Koa()

app.use(bodyParser()) // Use a third-party library for parsing
app.use((ctx, next) = > {
  console.log(ctx.request.body)
})

app.listen(8000.() = > {
  console.log('Server started successfully')})Copy the code

5. Form-data parsing in KOA

Installing third-party libraries

npm install koa-multer

Generally, files are uploaded

const Koa = require('koa')
const bodyParser = require('koa-bodyparser')
const multer = require('koa-multer')
// const Router = require('koa-router')
const app = new Koa()

// const loginRouter = new Router({prefix: '/login'})
const upload = multer()

app.use(bodyParser())
app.use(upload.any())
app.use((ctx, next) = > {
  console.log(ctx.req.body)
  ctx.response.body = 'hello'
})
// loginRouter.post('/',upload.any(), (ctx, next) => {
// console.log(ctx.req.body)
// console.log(ctx.request.body)
// })
// app.use(loginRouter.routes())

app.listen(8000.() = > {
  console.log('Server started successfully')})Copy the code

Two ways, the other way is commented out

6. Upload files

const Koa = require('koa')
const Router = require('koa-router')

const app = new Koa()
const uploadRouter = new Router({prefix: '/upload'})

// The server runs and automatically generates the destination folder
const upload = multer({
  dest: './uploads/'
})

uploadRouter.post('/avatar'.(ctx, next) = > {
  console.log(ctx.req.file)
  ctx.response.body = 'Profile picture uploaded successfully'
})

app.use(uploadRouter.routes())

app.listen(8000.() = > {
  console.log('Server started successfully')})Copy the code

7. Response data

app.use((ctx, next) = > {
  // ctx.response.body = {
  // }
  // Set the status code
  ctx.status = 200
  // Set the content
  ctx.response.body = []
})
Copy the code

8. Static server

Installing third-party libraries

npm install koa-static

const Koa = require('koa')
const koaStatic = require('koa-static')

const app = new Koa()
app.use(koaStatic('/home'))

app.listen(8000.() = > {
  console.log('Server started successfully')})Copy the code

12. Differences between KOA and Express

  • Express is complete and powerful, which helps us build in a lot of useful features;
  • Koa is clean and free, it only contains the core functionality and does not restrict our use of other middleware. Even the most basic get and post are not provided to us in the app; We need to determine the request mode or other functionality by ourselves or by the route;

The next () function

  • Express does not return a promise
  • Koa returns a promise

The onion model

13, MySQL,

1. Number type

MySQL supports the following data types: number type, date and time type, string (character and byte) type, space type and JSON data type.

  • MySQL has many numeric types:

    • INTEGER Numeric types: INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT.

    • Floating-point numbers: FLOAT, DOUBLE (FLOAT is 4 bytes, DOUBLE is 8 bytes);

    • Exact number types: DECIMAL, NUMERIC (DECIMAL is an implementation of NUMERIC);

2. Date type

  • The value of YEAR is displayed in YYYY format
    • Ranges 1901 to 2155, and 0000.
  • The DATE type is used for values that have a DATE part but no time part:
    • DATE is displayed in the format YYYy-MM-DD.
    • The value ranges from ‘1000-01-01’ to ‘9999-12-31’.
  • The DATETIME type is used for values that contain the date and time parts:
    • DATETIME Displays a value in the format ‘YYYy-MM-dd hh: MM :ss’;
    • The value ranges from 1000-01-01 00:00:00 to 9999-12-31 23:59:59.
  • The TIMESTAMP data type is used for values that contain both the date and time parts:
    • TIMESTAMP displays the value in the format ‘YYYY-MM-DD hh: MM :ss’;
    • But it is within the UTC time range: ‘1970-01-01 00:00:01’ to ‘2038-01-19 03:14:07’;
  • In addition: DATETIME or TIMESTAMP values can include a fraction of the last fractional second in up to microsecond (6 bits) accuracy
    • For example, DATETIME can range from ‘1000-01-01 00:00:00.000000’ to ‘9999-12-31 23:59:59.999999’;

3. The value is a string

  • CHAR is a fixed length when the table is created. The length can be any value between 0 and 255.
    • When queried, the following space will be deleted.
  • A value of type VARCHAR is a variable length string. The length can be specified from 0 to 65535.
    • When queried, the following space is not deleted.
  • The BINARY and VARBINARY types are used to store BINARY strings. They store byte strings.
    • Dev.mysql.com/doc/refman/…
  • Blobs are used to store large binary types;
  • TEXT is used to store large string types;

4. Use of aggregate functions

Figure out the sum of mobile phone pricesselect SUM(price) totalPrice from'products' # ask huawei mobile phone price sumselect SUM(price) totalPrice from `products` where brand ='huawei'# Ask huawei for the average price of a Huawei phoneselect AVG(price) totalPrice from `products` where brand ='huawei'# Highest and lowestselect MAX(price) from = `products`
select MIN(price) from ='products' #select COUNT(*) from `products` where brand = 'huawei'
select COUNT(DISTINCT price) from `products`
Copy the code

5.GROUP BY

select brand,AVG(price),COUNT(*),AVG(score) from `profucts` GROUP BY brand
Copy the code

6. The use of HAVING

The having function mainly adds a restriction to groud by

select brand,AVG(price) avgPrice,COUNT(*),AVG(score) from `profucts` GROUP BY brand HAVING avgPrice > 2000
Copy the code
  • Demand: Find the average price of a phone with a rating greater than 7.5
    • Upgrade: Find out the phones with a score greater than 7.5, and figure out the average price according to the brand category
select brand, AVG(price) from 'products' where score > 7.5 GROUP BY brand
Copy the code

7. The foreign key

A. Create a foreign key

# Add the field later firsttable `profucts` ADD `brand_id` INT# Change brand_id to foreign keyalter table `products` add foreign key(brand_id) references brand (id);
Copy the code

B. Update or delete data when the foreign key exists

We can set several values for update or delete:

  • RESTRICT (default) : When updating or deleting a record, RESTRICT checks to see if there are foreign key records associated with the record. If there are foreign key records, an error is reported, so that the update or deletion is not allowed.
  • NO ACTION: Is the same as RESTRICT and is defined in the SQL standard.
  • CASCADE: When updating or deleting a record, it checks to see if there is a foreign key record associated with the record. If there is:
    • Update: Then the corresponding record is updated;
    • Delete: Then the associated records will be deleted;
  • SET NULL: When a record is updated or deleted, it checks to see if there is a foreign key record associated with the record and sets the corresponding value to NULL if there is
Step 1: View the table structure:SHOW CREATE TABLE`products`; Step 2: Delete the previous foreign keyALTER TABLE `products` DROP FOREIGNKEY products_ibfk_1; # Step 3: Add a new foreign key and set the new actionALTER TABLE `products` ADD FOREIGN KEY (brand_id)
					   REFERENCES brand(id)
					   ON UPDATE CASCADE ON DELETE CASCADE;
Copy the code

8. Query multiple tables

A. The Obtained Cartesian product

SELECT * FROM `products`, `brand`;

SELECT * FROM `products`, `brand` WHERE `products`.brand_id = `brand`.id;
Copy the code

B. SQL JOIN multiple tables

C. left connection

What we want to get is all the data on the left (mainly in the left table) :

LEFT [OUTER] JOIN = LEFT [OUTER] JOIN

SELECT * FROM `products` LEFT JOIN `brand` ON `products`.brand_id = `brand`.id;

SELECT * FROM `products` LEFT JOIN `brand` ON `products`.brand_id = `brand`.id
WHERE brand.id IS NULL;
Copy the code

D. the right connection

What we want to get is all the data on the right (mainly table) :

RIGHT [OUTER] JOIN [OUTER]

SELECT * FROM `products` RIGHT JOIN `brand` ON `products`.brand_id = `brand`.id;

SELECT * FROM `products` RIGHT JOIN `brand` ON `products`.brand_id = `brand`.id
WHERE products.id IS NULL;
Copy the code

E. the connection

An inner join indicates that the table on the left and the table on the right have corresponding data associations

Inner JOIN can be written in other ways: CROSS JOIN or JOIN can be written;

SELECT * FROM `products` INNER JOIN `brand` ON `products`.brand_id = `brand`.id;
Copy the code

And we’ll see that it works exactly the same way we did it before

SELECT * FROM `products`, `brand` WHERE `products`.brand_id = `brand`.id;
Copy the code

** But they mean different things: **

  • SQL statement 1: inner join, which means that when two tables are joined, the relationship between the data will be constrained to determine the results of the subsequent query;
  • SQL statement 2: where condition, represents the first cartesian product, based on the Cartesian product data to select where condition;

F. all connections

The SQL specification uses FULL JOIN, but MySQL does not support it. We need to use UNION to implement it:

(SELECT * FROM `products` LEFT JOIN `brand` ON `products`.brand_id = `brand`.id WHERE `brand`.id IS NULL)
UNION
(SELECT * FROM `products` RIGHT JOIN `brand` ON `products`.brand_id = `brand`.id WHERE `products`.id IS NULL);
Copy the code

9. Connect query PPT16

10. Objects and arrays

A. Convert the queried array into an object (one to many)

select products.id as id,products.title title
	   JSON_OBJECT('id',title)
from products left join bramd on products.brand_id = brand.id
Copy the code

B. Organize multiple queried arrays into objects and put them in arrays (many-to-many)

SELECT stu.id id, stu.name stuName, stu.age stuAge, cs.name csName, cs.price csPrice
JSON_ARRAYAGG(JSON_OBJECT(('id', cs.id. 'name', cs.name))
FROM `students` AS stu
RIGHT JOIN `students_select_courses` ssc On stu.id = ssc.student_id
RIGHT join `courses` cs on ssc.course_id = cs.id
GROUP BY stu.id
Copy the code

14. Node operates mysql

1. Basic use

Install mysql2

npm install mysql2

const mysql = require('mysql2')

// 1. Create a database connection
const connection = mysql.createConnection({
  host: 'localhost'.port: 3306.database: 'school'.user: 'root'.password: 'root'
})

// 2. Run the SQL statement
const statement  `select * from students`

connection.query(statement, (err, res, fields) = > {
  console.log(res)
  connection.destroy()
})
Copy the code

2. Preprocessing statements (recommended)

A bit:

  • More secure and prevents SQL injection
  • Better performance
const mysql = require('mysql2')

// 1. Create a database connection
const connection = mysql.createConnection({
  host: 'localhost'.port: 3306.database: 'school'.user: 'root'.password: 'root'
})
// 2. Execute the preprocessing statement
const statement = `select * from students where age > ? `

connection.execute(statement, [18].(err, res) = > {
  console.log(res)
  connection.destroy()
})
Copy the code

3. The connection pool

When multiple requests are sent for data, the performance is poor until the last connection is released. Mysql2 provides connection pooling for us

const mysql = require('mysql2')

// 1. Create connection pools
const connections = mysql.createPool({
  host: 'localhost'.port: 3306.database: 'school'.user: 'root'.password: 'root'.connectionLimit: 10
})
// 2. Use connection pool
const statement = `select * from students where age > ? `
connections.execute(statement, [18].(err, res) = > {
  console.log(res)
})
Copy the code

Promise way

connection.promise().execute(statement, [18]).then(res= > {
  console.log(res[0]);
}).catch(err= > {
  console.log(err);
})
Copy the code

4. Basic use of sequelize

Install sequelize and mysql2

npm install mysql2 sequelize

const { Sequelize } = require('sequelize')

const sequelize = new Sequelize('school'.'root'.'root', {
  host: 'localhost'.dialect: 'mysql'
})

sequelize.authenticate().then(() = > {
  console.log('Database connection successful')
}).catch( err= > {
  console.log('Failed to connect to database')
  console.log(err)
})
Copy the code

5. Add or modify the sequelize table operation

const { Sequelize, DataTypes, Model, Op } = require('sequelize')

const sequelize = new Sequelize('school'.'root'.'root', {
  host: 'localhost'.dialect: 'mysql'
})

// Test the connection
sequelize.authenticate().then(() = > {
  console.log('Database connection successful')
}).catch(err= > {
  console.log('Failed to connect to database')
  console.log(err)
})

// Create a relational mapping
class Student extends Model { }
Student.init({
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true.autoIncrement: true
  },
  name: {
    type: DataTypes.STRING,
    allowNull: false
  },
  age: {
    type: DataTypes.INTEGER,
  }
}, {
  tableName: 'students'.createdAt: false.updatedAt: false,
  sequelize
})

async function queryName () {
  // 1. Query all the contents in the database
  const res = await Student.findAll({
    where: {
      age: {
        [Op.gte]: 18 // Over 18 years old}}})console.log(res)

  // 2. Insert data
  const result = await Student.create({
    name: 'yogln'.age: 22
  })
  console.log(result)

  // 3. Update data
  const result = await Student.update({
    age: 100}, {where: {
      id: 7}})console.log(result)
}
queryName()
Copy the code

6. Perform a one-to-many operation on the sequelize table

const { Sequelize, DataTypes, Model, Op } = require('sequelize')

const sequelize = new Sequelize('school'.'root'.'root', {
  host: 'localhost'.dialect: 'mysql'
})

// Test the connection
sequelize.authenticate().then(() = > {
  console.log('Database connection successful')
}).catch(err= > {
  console.log('Failed to connect to database')
  console.log(err)
})

// Create a relational mapping
class Courses extends Model { }
Courses.init({
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true.autoIncrement: true,},name: {
    type: DataTypes.STRING,
    allowNull:false,},price: DataTypes.INTEGER
}, {
  tableName: 'courses'.createdAt: false.updatedAt: false,
  sequelize
})

class Student extends Model { }

Student.init({
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true.autoIncrement: true
  },
  name: {
    type: DataTypes.STRING,
    allowNull: false
  },
  age: {
    type: DataTypes.INTEGER,
  },
  courseId: {
    field: 'id'.type: DataTypes.INTEGER,
    // Foreign key constraints
    references: {
      model: Courses,
      key: 'id'}}}, {tableName: 'students'.createdAt: false.updatedAt: false,
  sequelize
})


// Link the two tables together
Student.belongsTo(Courses, {
  foreignKey: 'courseId'
})

async function queryName () {
  const res = await Student.findAll({
    include: {
      model: Courses 
    }
  })
  console.log(res)
}
queryName()
Copy the code

7. Many-to-many operations on the sequlize table

const { Sequelize, DataTypes, Model, Op, QueryTypes } = require('sequelize')

const sequelize = new Sequelize('school'.'root'.'root', {
  host: 'localhost'.dialect: 'mysql'
})


// Courses
class Courses extends Model { }
Courses.init({
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true.autoIncrement: true,},name: {
    type: DataTypes.STRING,
    allowNull: false,},price: DataTypes.INTEGER
}, {
  tableName: 'courses'.createdAt: false.updatedAt: false,
  sequelize
})
// Student
class Student extends Model { }
Student.init({
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true.autoIncrement: true
  },
  name: {
    type: DataTypes.STRING,
    allowNull: false
  },
  age: {
    type: DataTypes.INTEGER,
  },
  courseId: {
    field: 'id'.type: DataTypes.INTEGER,
    // Foreign key constraints
    references: {
      model: Courses,
      key: 'id'}}}, {tableName: 'students'.createdAt: false.updatedAt: false,
  sequelize
})

// StudentCourses
class StudentCourses extends Model { }
StudentCourses.init({
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true.autoIncrement: true
  },
  StudentId: {
    type: DataTypes.INTEGER,
    references: {
      model: Student,
      key: 'id'
    },
    field: 'student_id'
  },
  courseId: {
    type: DataTypes.INTEGER,
    references: {
      model: Courses,
      key: 'id'
    },
    field: 'course_id'
  }
},{
  tableName: 'students_select_courses'.createdAt: false.updatedAt: false,
  sequelize
})

// Many-to-many relationships
Student.belongsToMany(Courses, {
  through: StudentCourses,
  foreignKey: 'student_id'.otherKey: 'course_id'
})

Courses.belongsToMany(Student, {
  through: StudentCourses,
  foreignKey: 'course_id'.otherKey: 'student_id'
})

/ / query
async function query() {
  const res = await Student.findAll({
    include: {
      model: Courses
    }
  })
  console.log(res)
}

query()
Copy the code

Allow cross-domain

Take the KOA framework for NodeJS as an example

ctx.set('Access-Control-Allow-Origin', '*'); ctx.set('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild'); ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS'); if (ctx.method == 'OPTIONS') { ctx.body = 200; } else { await next(); }});Copy the code

The front end can also be configured across domains

// exports = {proxy server: {proxy: {// request 'http://121.4.103.100', '/ API 'if the requested address starts with/API: {target: 'http://121.4.103.100', changeOrigin: True, pathRewrite: {' ^ / API ':' / / request API can be replaced with "}}}}}Copy the code

Using the uri of/API/XXX/XXX, the proxy will replace/API with/SRC /main.js

import axios from 'axios'; Import VueAxios from 'vue-axios' // URL configured for the interface proxy, i.e. / API axios.defaults.baseurl = '/ API '; axios.defaults.timeout = 8000; Vue.use(VueAxios, axios);Copy the code