当前位置:网站首页>Koa2 learning notes
Koa2 learning notes
2022-06-11 02:22:00 【Extremes~】
List of articles
- Introduce
- One 、Koa2 install
- Two 、 Entrance file
- 3、 ... and 、 Onion model
- Four 、 Route installation
- 5、 ... and 、 Route splitting
- 6、 ... and 、 Unified exception handling
- 7、 ... and 、 operation mysql Function encapsulation
- 8、 ... and 、 The backend allows cross domain
- Nine 、 Read static resource file
- Ten 、POST request
- 11、 ... and 、 File read and write
Introduce
Koa It's a new one web frame , from Express The same people behind the scenes , Be dedicated to web The application and API A smaller area of development 、 More expressive 、 More robust cornerstone . By using async function ,Koa Discard the callback function for you , And strongly enhances error handling . Koa No middleware is bundled , It provides an elegant approach , Helps you write server-side applications quickly and happily .
One 、Koa2 install
Create a blank Directory , And then go to the terminal , And on the terminal koa Installation :
# Project initialization
cnpm init -y
# install koa2
cnpm i koa2 -S
Two 、 Entrance file
Create in project root app.js file , And generated in the previous operation package.json Internal configuration :
{
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node app.js"
},
}
stay app.js in :
const Koa = require('koa2');
const app = new Koa()
const port = 5050;
// const router = require('./router/index')
// const cors = require('koa2-cors')
// const static = require('koa-static')
// const path = require('path')
// Unified exception handling
const errorHandler = require('./utils/errorHandler')
/*
app.use() The method is : Add the given middleware method to this application . To put it simply, call the middleware
app.use() return this, So it can be expressed in a chain
*/
// app.use(static(path.join(__dirname+'/assets'))) // Read static file
// app.use(cors()); // cors Middleware must be written before routing ( The backend allows cross domain )
// app.use(router.routes(), router.allowedMethods()); // Incoming routing
errorHandler(app)
app.use(async (ctx)=>{
ctx.body = "Hello, Koa";
// ctx.body yes ctx.response.body Abbreviation
})
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`)
})
And then run npm start , And enter... In the browser http://localhost:5050/ You can see the page effect .
3、 ... and 、 Onion model

Koa and Express Will use middleware ,Express The middleware is executed sequentially , From the first middleware execution to the last middleware , Respond :
Koa It starts from the first middleware , encounter next Go to the next middleware , Until the last middleware , In reverse order , Execute the previous middleware next Later code , The response is not sent until the end of the first middleware execution .
The specific code of the onion model can be understood as :
// Whole koa Entry documents for the project
// Constructors
const Koa = require('koa2');
// Declare an instance
const app = new Koa()
// Port number
const port = 5050;
// Call middleware
app.use(async (ctx, next) => {
// Return the data to the page
// ctx.response.body = ' This is a koa home page ';
console.log(1)
await next()
console.log(1)
})
app.use(async (ctx, next) => {
console.log(2)
await next()
console.log(2)
})
app.use(async (ctx, next) => {
console.log(3)
})
// baidu.com ip+port
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`)
})
After the browser is refreshed , The order the console gets is
1
2
3
2
1
Now you can see , We go through next You can run the next middleware first , When the middleware is finished , Continue to run the current next() Later code .
Four 、 Route installation
When you need to match different routes , Can install
npm i koa-router
take app.js It is amended as follows
const Koa = require('koa2');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
const port = 5050;
router.get('/', async (ctx)=>{
ctx.body = " home page ";
})
router.get('/list', async (ctx)=>{
ctx.body = " List of pp. ";
})
app.use(router.routes(), router.allowedMethods());
app.listen(port, ()=>{
console.log('Server is running at http://localhost:'+port);
})
here , Refresh to the browser and add... At the end of the address bar /list You can get the home page and list page .
// call router.routes() To assemble a matched route , Return a merged middleware
// call router.allowedMethods() Get a middleware , When a non-conforming request is sent , Returns the405 Method Not Allowedor501 Not Implemented
allowedMethods Method can be configured as follows :
app.use(router.allowedMethods({
// throw: true, // Throw an error , Instead of setting the response header status
// notImplemented: () => ‘ The function required by the current request is not supported ’,
// methodNotAllowed: () => ‘ Unsupported request mode ’
}))
5、 ... and 、 Route splitting
Sometimes we need to split routes , such as :
All sub routes under the list page ( That is, requested by the front end api) All sub routes of the home page should be handled separately , Then you need to split the route .
1、 establish router Folder
establish router Folder , And create :index.js ( Route master entry file )、home.js ( Homepage general routing file )、list.js ( List page total routing file )、errorPage.js( Error page ):
# app.js
const router = require('./router/index')
app.use(router.routes(), router.allowedMethods());
# index.js
// Incoming routing
const Router = require('koa-router');
// const list = require('./list');
const router = new Router();
const home = require('./home')
const list = require('./list')
const login = require('./login')
router.get('/home', async (ctx) => {
ctx.body = ' home page ';
})
router.get('/list', async (ctx) => {
ctx.body = ' List of pp. '
})
router.use('/list', list.routes(), list.allowedMethods())
router.use('/home', home.routes(), home.allowedMethods())
router.use('/login', login.routes(), login.allowedMethods())
router.redirect('/', '/home') // Open the web page and automatically redirect to the home page
module.exports = router
# home.js
// all api Interfaces are in this file
const Router = require('koa-router');
const home = new Router();
// const db = require('../utils/db')
home.get('/fruit', async (ctx) => {
ctx.body = ' home page - Fruits ';
})
home.get('/wanju', async (ctx) => {
// Access database , Get the data and return it to the front end
/* let mydata = await new Promise((resolve, reject) => {
let sql = 'select * from article';
db.query(sql, (err, data) => {
if (err) throw err;
// Process the data eg:
data.map(val => {
val.imgUrl = 'http://localhost:5050'+val.imgUrl
})
resolve(data)
})
})
ctx.body = mydata;
*/
ctx.body = " home page - toy ";
})
home.get('/film', async (ctx) => {
ctx.body = ' home page - Cinema ticket ';
})
module.exports = home
# list.js
// all api Interfaces are in this file
const Router = require('koa-router');
const list = new Router();
list.get('/fruit', async (ctx) => {
ctx.body = ' List of pp. - Fruits ';
})
list.get('/wanju', async (ctx) => {
ctx.body = ' List of pp. - toy ';
})
list.get('/film', async (ctx) => {
ctx.body = ' List of pp. - Cinema ticket ';
})
module.exports = list
# The login page login.js ( Use your own database , Need to create extra db.js file , Later said )
// all api Interfaces are in this file
const Router = require('koa-router');
const login = new Router();
const bodyparser = require('koa-bodyparser')
const db = require('../utils/db')
const jwt = require('jsonwebtoken')
login.use(bodyparser()) // After invoking the middleware , You can get the data from the front end .
login.post('/register', async (ctx) => {
console.log(ctx.request.body)
let account = ctx.request.body.account; // The account from the front end
let pwd = ctx.request.body.pwd;
// Determine whether this account exists in the database , If so, verify the password , If not, add a record
let sql = `select * from users where account = '${account}'`
let myarr = await new Promise((resolve, reject) => {
return db.query(sql, (err, data) => {
if (err) throw err;
console.log(data)
resolve(data)
})
})
if (myarr.length > 0) {
// Prove that you have this account number , Verify password
console.log(myarr)
if (myarr[0].pwd == pwd) {
ctx.body = {
code: 200,
msg: " Login successful ",
token: myarr[0].token,
account: myarr[0].account
}
} else {
ctx.body = {
code: 300,
msg: " Wrong account or password "
}
}
} else {
// There is no account , To register ( Add a piece of data )
let token = jwt.sign({ account: account, pwd: pwd }, 'secret', {expiresIn:3600})
let insertSql = `insert into users(account, pwd, token) values ('${account}', '${pwd}', '${token}')`
ctx.data = await new Promise((resolve, reject) => {
return db.query(insertSql, (err, data) => {
if (err) throw err;
console.log(data)
ctx.body = {
code: 200,
msg: " Registered successfully ",
token: token,
account: account
}
resolve(ctx.data)
})
})
}
// ctx.body = ` Log in to register `;
})
module.exports = login
#errorPage.js
const Router = require('koa-router');
const errorPage = new Router();
errorPage.get('/', async (ctx) => {
ctx.body = " The access page does not exist "
})
module.exports = errorPage
To browser refresh localhost:5050/home And localhost:5050/list You can get the home page and list page .
2、 Route redirection
If you want to go straight from localhost:5050 Redirect to localhost:5050/home
Can be in router/index.js Do the following configuration in :
router.use('/home', home.routes(), home.allowedMethods());
...
router.redirect('/', '/home');
3、404 Invalid route
If an invalid route is accessed , Can return to 404 page :
stay router Next errorPage.js :
const Router = require('koa-router');
const errorPage = new Router();
errorPage.get('/', async (ctx) => {
ctx.body = " The access page does not exist "
})
module.exports = errorPage
stay app.js I quote :
// Jump to all pages that do not match 404
app.use(async (ctx, next) => {
await next();
if (parseInt(ctx.status) === 404) {
ctx.response.redirect("/404")
}
})
app.use(router.routes(), router.allowedMethods());
6、 ... and 、 Unified exception handling
Avoid writing by yourself every time 404 or 200 Go back , So we can create utils/errorHandler.js :
module.exports = (app) => {
app.use(async(ctx, next) => {
let status = 200;
let data = "";
try {
await next();
status = ctx.status;
} catch (err) {
status = 500;
}
if (status >= 400) {
switch (status) {
case 400:
case 404:
case 500:
data = status;
break;
default:
data = 'other';
break;
}
}
ctx.response.status = status;
console.log(data)
})
}
And then in app.js Introduction in :
const errorHandler = require('./utils/errorHandler.js');
app.use(router.routes(), router.allowedMethods());
...
errorHandler(app);
7、 ... and 、 operation mysql Function encapsulation
First , Installation in the project mysql:
yarn add mysql // perhaps cnpm i mysql
stay utils Create one in the directory db.js file :
let mysql = require('mysql')
let pool = mysql.createPool({
host: 'localhost', // Connected servers ( After the code is hosted online , Need to change to Intranet IP, Not the Internet )
port: 3306, // mysql The port on which the service runs
database: 'c_data', // Selected Libraries
user: 'root', // user name
password: 'root' // User password
})
// The basis for adding, deleting, modifying and querying databases
function query(sql, callback) {
pool.getConnection(function (err, connection) {
connection.query(sql, function (err, rows) {
callback(err, rows)
connection.release() // Disconnect
})
})
}
exports.query = query
Call mode :
Suppose you want to visit the home page (‘/home’) when , To query a table article All the data in , You can do the following :
const db = require('../utils/db.js');
home.get('/wanju', async (ctx) => {
let mydata = await new Promise((resolve, reject) => {
// Access database , Get the data and return it to the front end
let sql = 'select * from article';
db.query(sql, (err, data) => {
if (err) throw err;
// Process the data eg:
data.map(val => {
val.imgUrl = 'http://localhost:5050'+val.imgUrl
})
resolve(data)
})
})
ctx.body = mydata;
})
8、 ... and 、 The backend allows cross domain
The front end wants to cross domain , You can set proxy. If the backend allows cross domain , You can do the following :
// install koa2-cors
cnpm i koa2-cors
// here cors Middleware must be written before routing app.js
app.use(cors());
app.use(router.routes(), router.allowedMethods())
Nine 、 Read static resource file
First , Create... In the root directory of the project assets after , Put the picture resource folder images Put it in it , And do the following :
// install koa-static
cnpm install koa-static
// introduce
const path = require('path')
const static = require('koa-static')
// Get static resource folder
app.use(static(path.join(__dirname+'/assets')));
...
app.use(router.routes(), router.allowedMethods())


Suppose one of them txt The document is called 1.txt, So let's open the browser , visit :http://localhost:5050/1.txt You can get . here
Be careful :
There is no need to write on the path assets, Because we have specified that when accessing resources , http://localhost:5050 Auto point assets Folder .
Ten 、POST request
1、 Build table
Set the field to account and pwd
create table users (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
account VARCHAR(20) NOT NULL COMMENT ' account number ',
pwd VARCHAR(20) NOT NULL COMMENT ' password ',
token LONGTEXT NOT NULL COMMENT ' token '
);
2、form Form page
stay assets Create index.html :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<label for="account"> account number </label>
<input type="text" value="" name="account" class="account" placeholder=" Please enter your account number " />
<br><br>
<label for="pwd"> password </label>
<input type="password" value="" name="pwd" class="pwd" placeholder=" Please input a password " />
<br><br>
<button class="btn"> Sign in / register </button>
</body>
</html>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$('.btn').click(()=>{
$.ajax({
url: "/login/register",
method: "POST",
data: {
account: $('.account').val(),
pwd: $('.pwd').val()
},
success(res){
console.log(res)
},
error(err){
console.log(err)
}
})
})
</script>
Direct access in browser http://localhost:5050/index.html You can enter the form page .
3、 Install middleware
install koa-bodyparser And jsonwebtoken middleware :
// koa-bodyparser Used to get post Request data
cnpm install koa-bodyparser --save
// jsonwebtoken Used to generate token
cnpm install jsonwebtoken --save
JWT
Use... In the route where the user logs in jwt.sign To generate token, A total of three parameters are defined , The first is to deposit token Information about , The second is token Key , and config/passport.js The key of the configuration is the same , The third is the storage time ,3600 An hour , Finally back to token, We need to put it in front Bearer:
const jwt = require('jsonwebtoken')
const token = jwt.sign({ myaccount: myaccount, mypwd: mypwd }, 'secret', { expiresIn: 3600 })
let obj = {
token,
msg: ' Login successful '
}
resolve(obj)
4、 add to post Interface
stay router/login.js Add :
const bodyParser = require('koa-bodyparser')
login.use(bodyParser());
login.post('/register', async (ctx)=>{
console.log(ctx.request.body); // You can print the data
ctx.response.body = " Log in or sign up for "
})
5、 Login and automatic registration
// all api Interfaces are in this file
const Router = require('koa-router');
const login = new Router();
const bodyparser = require('koa-bodyparser')
const db = require('../utils/db')
const jwt = require('jsonwebtoken')
login.use(bodyparser()) // After invoking the middleware , You can get the data from the front end .
login.post('/register', async (ctx) => {
console.log(ctx.request.body)
let account = ctx.request.body.account; // The account from the front end
let pwd = ctx.request.body.pwd;
// Determine whether this account exists in the database , If so, verify the password , If not, add a record
let sql = `select * from users where account = '${account}'`
let myarr = await new Promise((resolve, reject) => {
return db.query(sql, (err, data) => {
if (err) throw err;
console.log(data)
resolve(data)
})
})
if (myarr.length > 0) {
// Prove that you have this account number , Verify password
console.log(myarr)
if (myarr[0].pwd == pwd) {
ctx.body = {
code: 200,
msg: " Login successful ",
token: myarr[0].token,
account: myarr[0].account
}
} else {
ctx.body = {
code: 300,
msg: " Wrong account or password "
}
}
} else {
// There is no account , To register ( Add a piece of data )
let token = jwt.sign({ account: account, pwd: pwd }, 'secret', {expiresIn:3600})
let insertSql = `insert into users(account, pwd, token) values ('${account}', '${pwd}', '${token}')`
ctx.data = await new Promise((resolve, reject) => {
return db.query(insertSql, (err, data) => {
if (err) throw err;
console.log(data)
ctx.body = {
code: 200,
msg: " Registered successfully ",
token: token,
account: account
}
resolve(ctx.data)
})
})
}
// ctx.body = ` Log in to register `;
})
module.exports = login
here , The front end does this post After the request , You will get the corresponding data .
11、 ... and 、 File read and write
stay utils Create under directory file.js
const fs = require('fs')
const path = require('path')
const db = require('./db')
// Read assets In the catalog 1.txt and 2.txt function , Pass in the parameter file name
function readFileFn(arg) {
return new Promise((resolve, reject) => {
let mypath = path.join(__dirname, `../assets/${arg}.txt`)
fs.readFile(mypath, (err, data) => {
if (err) throw err;
resolve(data.toString())
console.log(data.toString())
})
})
}
// function readFileFn(arg) {
// let mypath = path.join(__dirname, `../assets/${arg}.txt`)
// fs.readFile(mypath, (err, data) => {
// if (err) throw err;
// console.log(data.toString()) // The file read here is a binary file stream , So we need to convert the string
// })
// }
// let text1 = readFileFn('1')
// let text2 = readFileFn('2')
// Insert the read content into a specific structure , Insert database
let fn = async () => {
let text1 = await readFileFn('1')
let text2 = await readFileFn('2')
let arr = [
{ id: 0, title: " A set of frameworks and multiple platforms Mobile & The desktop ", author: " Zhang Sanfeng ", date: "2022-05-21", imgUrl: "/images/dt.png", content: text1 },
{ id: 1, title: " Progressive JavaScript frame ", author: " Little fish ", date: "2022-05-21", imgUrl: "/images/dt.png", content: text2 }
]
arr.map(val => {
let sql = `insert into article values(${val.id}, '${val.title}', '${val.author}', '${val.date}', '${val.imgUrl}', '${val.content}')`
db.query(sql, (err, data) => {
if (err) throw err;
console.log(data)
})
})
}
fn()
// const data = [
// {id: 0, icon: './images/angluar.gif', subtitle: " Learn to use Angular Building applications , Reuse these codes and capabilities on a variety of different platform applications ", title: " A set of frameworks and multiple platforms Mobile & The desktop "},
// { id: 1, icon: './images/vue.gif', subtitle: " A thriving ecosystem , You can scale freely between a library and a complete set of frames ", title: " Progressive JavaScript frame " }
// ]
// data.map(val => {
// let sql = `insert into zixun values (${val.id}, '${val.title}', '${val.subtitle}', '${val.icon}')`
// db.query(sql, (err, data) => {
// if (err) console.log(err)
// console.log(data)
// })
// })
边栏推荐
- [3.delphi common components] 6 scroll bar
- InfoQ 极客传媒 15 周年庆征文|容器运行时技术深度剖析
- 从测试零基础到测试架构师,这10年,他是这样让自己成才的
- 接口自动化核心知识点浓缩,为面试加分
- Do tween record
- Unity3d detects that the object is not within the range of the camera
- 【Qt】error: QApplication: No such file or directory 解决方案
- About stepping on the pit diary and the association of knowledge points
- 浅析直播间海量聊天消息的架构设计难点
- 心态不能崩......
猜你喜欢

Unity serial port communication

CRS-5017

koa2学习笔记

10 years of domestic milk powder counter attack: post-90s nannies and dads help new domestic products counter attack foreign brands

During SSH configuration key login, you need to pay attention to whether the private key is set with a password

Understand the role of before and after Clearfixafter clear floating

软测人都该知道的七大原则

SAP smartforms page feed printing automatic judgment

Introduction and practice of QT tcp/udp network protocol (supplementary)

Find - (block find)
随机推荐
Oracle tablespaces, users, and authorization to users
Seven principles that should be known by software testers
Unity3d detects that the object is not within the range of the camera
Is it appropriate for a 27 - year-old girl to change her career from zero to software testing?
Go develop web
大厂测试员年薪30万到月薪8K,吐槽工资太低,反被网友群嘲?
switch case使用枚举类来比较
Sequence table exercises
Software testing interview reply: the technical side is not difficult for me, but the HR side is a hang up
环糊精金属有机骨架(β-CD-MOF)装载二巯丁二酸/大黄素/槲皮素/三氯蔗糖/二氟尼柳/奥美拉唑(OME)
Large screen - full screen, exit full screen
技术分享| 快对讲,全球对讲
Infinite level classification (or menu) design
2022 safety officer-a certificate special operation certificate examination question bank and simulation examination
双面材质【double sided】的Shader
InfoQ 极客传媒 15 周年庆征文|容器运行时技术深度剖析
Secret
In the past 10 years, from zero foundation testing to test architect, he has made himself successful
Enrichment of core knowledge points of interface automation to add points to the interview
Project records