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:
- Go straight to file X
- Find X.j s
- Find X.j son
- Find X.n ode
2. No corresponding file is found
Look for the index file in the directory
- Go directly to the file X/index.js
- Find the X/index. Js
- Find the X/index. Json
- 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:
-
Method 1: Add export before a method or variable
export const name = 'Ming' export const function sayHello(msg) { console.log(msg) } Copy the code
-
Method 2: export(not an object)
export { name, sayHello } Copy the code
-
Export aliases variables when exporting
export { name as fName, sayHello as fSayHello } Copy the code
There are three common import methods
-
Import {} from ‘./ path.js’
import { name } from '/ path. Js' //.js cannot be omitted Copy the code
-
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
-
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:
-
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
-
Join path Splicing
const path = path.join(basePath, fileName) Copy the code
-
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
-
Register on the NPM website
-
Enter the command on the terminal
npm login
-
Modify package.json,keywords,license, repository, etc
"repository": { "type": "git"."url": "Warehouse address" } Copy the code
-
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
- Execute script code first
- Execute the microtask queue
- 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
- Next Ticks queue: process. NextTick;
- Other microtask queues: THEN callbacks for promises, queueMicrotask
- Timers queue: setTimeout and setInterval
- IO queue: IO events
- Check queue :setImmediate
- 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