Node——express,mysql

Express

What is Express?

Express is a fast, open and minimalist web development framework based on the Node.js platform

basic use

Install

Run in the root directory where the project is located:

npm i [email protected]

Create a basic web server

//导入 express 
const express = require('express')
// 创建 web 服务器
const app = express()
//
app.get('/user/:id', (res, req) => {
    
    
    res.send()  //向客户端响应文本或字符串
    req.query() //默认是个空对象;可以获取到客户端发送过来的查询参数例 ?name=zs&age=20
    req.params //默认空对象,可以访问到URL中,通过: 匹配到的动态参数[:id]
    // :必须写 id可以任意修改,它是参数的名字
    //还可以写多个   'user/:id/:name/:age'
})
// 调用 app.listen(端口号, 启动成功后的回调函数) ,启动服务器
app.listen(80,() => {
    
    
    console.log('express server running at http://127.0.0.1')
})

Listen for GET requests

app.get('URL', function(res, req) {
    
    
  
})
// res : 请求对象(包含与请求相关的属性和方法)
// req : 响应对象(包含与响应相关的属性和方法)

Listen for POST requests

app.post('URL', function(res, req) {
    
    
    
})

express.static()

Through this function, we can create a static resource server very conveniently, and open access to files in a certain directory; the directory name storing static files will not appear in the url

app.use(express.static('public'))

Host multiple static resources

That is, calling the express.static() function multiple times

When accessing static resource files, the express.static() function will find the required files according to the order in which the directories are added

ALL+ shang

mount path prefix

app.use('/abc',express.static('./abc'))

mount prefix before path

nodemon

Monitor changes in project files. When the code is modified, nodemon will automatically restart the project for us

Install

npm install -g nodemon

use

Change node to nodemon

routing

The routing in express is the mapping relationship : the mapping relationship between the client's request and the server processing function

It is divided into three parts: the type of request (METHOD), the URL address of the request (PATH), and the processing function (HANDLER):

app.METHOD(PATH, HANDLER)

route matching

  • Match according to the order of definition
  • The corresponding processing function will only be called when the request type and the requested URL match successfully at the same time

Modular Routing

//导入 express
const express = require('express')
//创建路由对象
const router = express.Router()
//挂载具体的路由
router.get('/', (req, res) => {
    
    
    
})
router.post('/',(req, res) => {
    
    
    
})
//向外导出路由对象
module.exports = router

Register routing module

const express = require('express')
const app = express()
const router = require('./url')
//注册路由模块
app.use(router) 
app.use() //函数作用,注册全局中间件

Add a prefix to the routing module

app.use('/abc',router)

middleware

Format

function(req, res, next)

The role of the next function

The next function is the key to realize the continuous invocation of multiple middleware, and it means to transfer the flow relationship to the next middleware or route.

How to use middleware

const express = require('express')

const app = express()

//定义一个最简单的中间件函数
const mw = function(req, res, next) {
    
    
    
    
    //把流转关系转交给下一个中间件或路由
    next()
}

app.listen(80,() => {
    
    
    
})

Global middleware

Any request initiated by the client will trigger the middleware after reaching the server, which is called globally effective middleware

app.use(mw)

Short form global middleware

app.use((req, res, next) => {
    
    
    
    next()
})

effect:

Multiple middleware share the same req and res. Based on this feature, we can uniformly add custom properties or methods to the req and res objects in the upstream middleware for downstream middleware or routing to use

locally valid middleware

Middleware without app.use()

const express = require('express')

const app = express()

const mw1 = (req ,res ,next) => {
    
    
    next()
}
app.get('/',mw1,(req, res) => {
    
    
    //mw1只在此函数中生效
    //若有多个局部中间件 添加到mw1后面,用逗号(,)隔开
})

app.post('/',(req, res) => {
    
    
    
})

app.listen(80, () => {
    
    
    
})

Notes on using middleware

  • Be sure to register middleware before routing
  • Multiple middleware can be called continuously for processing
  • Don't forget to call the next() function
  • In order to prevent code logic confusion, do not write additional code after calling the next() function
  • When multiple middlewares are called continuously, req and res objects are shared between multiple middlewares

Classification of middleware

Route-level middleware

error level middleware

//定义错误级别的中间件, 捕获整个项目的异常错误, 从而防止程序的崩溃
app.use(err, req, res, next) => {
    
    
    res.send('Error:' + err.message)
}
//错误级别中间件要放在所有路由之后

Express built-in middleware

  1. express.static
  2. express.json parses request body data in JSON format
  3. express.urlencoded parses request body data in URL-encoded format

The req.body attribute accepts the request body data sent by the client;

If you do not configure an intermediate for parsing form data, req.body is equal to undefined by default

app.use(express.json())  //内置中间件
app.use(express.urlencoded({
    
    extended:false}))

used in routingreq.body

use of database

pk: primary key, unique identifier

NN: Value is not allowed to be empty

UQ: unique value

AI: value auto increment

Default/Expression : default value

What is SQL?

SQL is a structured query language, a programming language specially used to access and process databases. It allows us to manipulate the data in the database in the form of editing.

--note

From the [table] specified by FROM, query [all] data, * means [all columns]

select * from 表名称

From the [table] specified by FROM, query the data of the specified column name

select 列名称 from 表名称

Insert a new row of data into the data table

insert into 表名称(列1,列2...) values (值1, 值2,...)

modify the data in the table

update 表名称 set 列名称 = 新值 where 列名称 = 某值

Multiple column changes, separated by commas

  • update specifies which data to update
  • SET specifies the new value corresponding to the column
  • Use where to specify the update conditions

delete row in table

delete form table name where id=

Keywords are not case sensitive


where child clause

The where clause is used to limit the selection criteria.

<>和!=都表示不等号

and must satisfy multiple conditions at the same time

or either condition is satisfied

order by sorts the result set according to the specified column, the default is sorted in ascending order (ASC) (DESC keyword, can be sorted in descending order)

select * from users order by iddefault ascending

[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-tM1nzSVY-1647130047397)(C:\Users\Lenovo\Desktop\typora\img\orderby.png)]

select * from users order by id descdescending order

[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-e8nLNXfo-1647130047399)(C:\Users\Lenovo\Desktop\typora\img\orderbydesc.png)]

For multiple collations, separate them with commas


count(*) function

The count(*) function is used to return the total number of data items in the query result

select count(*) from 表名称

as keyword

alias the column

select username as uname, password as upwd from users

Operate MySQL in the project

npm install mysql

Establish a connection to the mysql database

const db = mysql.createPool({
    
    
    host: '127.0.0.1',  //数据库的 IP 地址
    user: 'root',  //登录数据库的账号
    password: 'admin123', //登录数据库的密码
    database: 'my_db_01' //指定要操作那个数据库
})

Test that the MySQL module is working properly

db.query('select 1',(err, results) => {
    
    
    if(err) return console.log(err.message)
    console.log(results)
})

Query all data in the users table

const sqlStr = 'select * from users'
db.query(sqlStr, (err, result) => {
    
    
    if(err) return console.log(err.message)
    //如果使用 select 查询语句,执行的结果为 数组
    console.log(result)
})

insert data

 //要插入到 users 表中的数据对象
const user = {
    
     username: 'Spider-Man', password: 'pcc121'}
//待执行的 SQL 语句, 其中英文的 ? 表示占位符
const sqlStr = 'insert into users(username, password) value(?, ?)'
//使用数组的形式依次为 ? 占位符指定具体的值
db.query(sqlStr, [user.username, user.password], (err, results) => {
    
    
	if(err) return console.log(err.message)
    //如果执行 insert into 插入语句, 则 results 是一个对象
    if(results.affectedRows === 1) {
    
     //判断是否插入成功
        console.log('插入数据成功')
    }
})

A convenient way to insert data

 //要插入到 users 表中的数据对象
const user = {
    
     username: 'Spider-Man', password: 'pcc121'}
//待执行的 SQL 语句, 其中英文的 ? 表示占位符
const sqlStr = 'insert into users SET ?'
//直接将数据对象作为占位符
db.query(sqlStr, user, (err, results) => {
    
    
    if(err) return console.log(err.message)
    //如果执行 insert into 插入语句, 则 results 是一个对象
    if(results.affectedRows === 1) {
    
     //判断是否插入成功
        console.log('插入数据成功')
    }
})

update data

const user = {
    
    id: 6, username: 'aaa', password: '000'}
const sqlStr = 'update users set username=?, password=? where id=?'
db.query(sqlStr, [user.username, user.password, user.id], (err, results) => {
    
    
    if(err) return console.log(err.message)
    //如果执行 insert into 插入语句, 则 results 是一个对象
    if(results.affectedRows === 1) {
    
     //判断是否插入成功
        console.log('更新成功')
    }
})

A convenient way to update data

// 要更新的数据对象
const user = {
    
     id = 7, username: 'aaaa', password: '0000'}
// 要执行的 sql 语句
const sqlStr = 'update users set ? where id=?'
//调用 db.query() 执行sql语句,同时使用数组依次为占位符指定具体的值
db.query(sqlStr, [user,user.id], (err, results) => {
    
    
    if(err) return console.log(err.message) 
    if(results.affectedRows === 1) {
    
    
        console.log('更新数据成功')
    }
})

delete data

const delete = 'delete from users where id=?'
db.query(sqlStr, 5, (err, results) => {
    
    
    if(err) return console.log(err.message)
    if(results.affectedRows === 1) {
    
    
        console.log('删除数据成功')
    }
})

mark for deletion

const sqlStr = 'update users set status=? where id=?'
db.query(sqlStr, [1, 6], (err, results) => {
    
    
    if(err) return console.log(err.message)
    if(results.affectedRows === 1) {
    
    
        console.log('删除数据成功')
    }
})

Front-end and back-end development models

Authentication

Server-side rendering uses Session authentication mechanism

The stateless nature of the HTTP protocol means that each HTTP request of the client is independent, there is no direct relationship between multiple consecutive requests, and the server is not destined to retain the state of each HTTP request.

How to break through the stateless limitation of HTTP?

A cookie is a string of no more than 4kb stored in the user's browser . It consists of a name, a value, and several other optional attributes used to control the validity period, security, and scope of use of the cookie.

Cookies under different domain names are independent. Whenever the client initiates a request, all unexpired cookies under the current domain name will be automatically sent to the server together.

Several major features of cookies: 1. Automatic sending 2. Independent domain name 3. Expiration time limit 4. 4KB limit

Role in identity authentication: When the client requests the server for the first time, the server sends an identity authentication cookie to the client in the form of a response header, and the client will automatically save the cookie in the browser.

Subsequently, when the client browser requests the server each time, the browser will automatically send the cookie related to identity authentication to the server in the form of a request header, and the server can find out the identity of the client

Cookies are not secure, please do not use cookies to store important and private data!

Improve the security of identity authentication

How sessions work

Install express-session

npm install express-session

configuration

const express = require('express')
const session = require('express-session')
const app = express()
app.use(
    session({
    
    
        secret: 'keyboard cat',
        resave: false,
        saveUninitialized: true
}))

store information

req.session.user = req.body

req.sesion.islogin = true

clear session

req.session.destroy()

Clear the session information saved by the server

Front-end and back-end separation using JWT authentication mechanism

JWT consists of three parts:

Header(头部).Payload(有效荷载).Signature(签名)

Use between the three. Separated

The Payload part is the real information of the user, which is a string generated after the user information is encrypted

Header and Signature are security-related parts, just to ensure the security of Token

How to use

Authorization: Bearer <token>

Install JWT related packages

npm install jsonwebtoken express-jwt

jsonwebtoken is used to generate JWT string

express-jwt is used to parse and restore JWT strings into JSON objects

Define the secret key

In order to ensure the security of the JWT string, we specifically define a sercet key for encryption and decryption:

  1. When generating the JWT string, you need to use the secret key to encrypt the user's information, and finally get the encrypted JWT string
  2. When parsing and restoring the JWT string to a JSON object, you need to use the secret key for decryption

const secreKey = 'itheima No1 ^_^'

Generate JWT string after login

Parameter 1: User's information object

Parameter two: encrypted key

Parameter 3: configuration object, you can configure the current token string

sign({
    
    username: userinfo.username}, secretKey, {
    
     expiresIn: '100s'})

Revert JWT string to JSON object

req.user() Get user information

Guess you like

Origin blog.csdn.net/m0_63300737/article/details/123453962