Gitee project address
Basic use of KOA
The directory structure
The use of koa
Creating an App
- Create an app.js file and import the required third-party plug-ins.
var Koa = require('koa');
var views = require('koa-views');
var bodyParser = require('koa-bodyparser');
const serve = require('koa-static');
const render = require('koa-art-template');
const path = require('path');
var {router} = require('./router');
Copy the code
- Create the app and listen on the port
var app = new Koa()
app.listen(3001)
Copy the code
Use the routing
- Configure routes. Configure routes in router.js
var Router = require('koa-router')
var router = new Router()
// Configure the route
router.get('/'.async (ctx) => {
// Return data equivalent to the original res.writehead () res.end()
ctx.body = 'home'
})
// Configure dynamic routing
router.get('/newsdetail/:id'.async (ctx) => {
console.log(ctx.params);
})
Copy the code
- Start routing in app.js
// router.allowedMethods() is called after all the routing middleware, at which point the response header is set according to ctx.status
app
.use(router.routes())
.use(router.allowedMethods())
Copy the code
Gets the GET request parameters
GET: There are two receiving modes: Query and queryString
- Query: Returns a formatted argument object
- Querystring: Returns a request string
router.get('/newsContent'.async (ctx) => {
// CTX gets the get pass value
console.log(ctx.query);
console.log(ctx.querystring);
// request in CTX
console.log(ctx.request);
console.log(ctx.params);
})
Copy the code
Receive POST request parameters
- Introducing middleware
/ /! Post parameter parsing middleware
app.use(bodyParser());
Copy the code
- To obtain parameters
router.post('/doAdd'.async(ctx) => {
// Get the data submitted by the form
console.log(ctx.request.body);
})
Copy the code
Use of middleware
- Application-level middleware
Middleware defined in app.js, executed before the route is matched.
app.use(async(ctx, next) => {
// Configure ctx.state.userInfo in middleware to use userInfo in any page
ctx.state.userInfo = 'name'
console.log('First middleware before Next');
// Continue matching down
await next()
console.log('First middleware after Next');
})
Copy the code
- Error middleware
When an error occurs, return to the corresponding page.
app.use(async(ctx, next) => {
console.log('Second middleware before Next');
await next()
console.log('Second middleware after Next');
// When all routes match, a 404 page is returned
if (ctx.status == 404) {
ctx.status = 404
ctx.body = 'This is a 404 page'}})Copy the code
- Routing level middleware
router.get('/news'.async(ctx, next) => {
console.log('This is a news page');
await next()
})
router.get('/news'.async(ctx) => {
ctx.body = 'This is a news page'
})
Copy the code
Middleware execution flow
- Execute the middleware from the top down
- Next is encountered to execute the next middleware
- After the middleware completes execution, the route is matched
- After the route matching is complete, the code after next of the middleware is executed from the bottom up
The output
- Enter ‘/news’ route. The route is successfully matched
Output:
- First middleware before Next
- Second middleware before next
- This is a news page
- Second middleware after next
- After the first middleware, Next
- Failed to match route by entering ‘/news1’ route
Output:
- First middleware before Next
- Second middleware before next
- Second middleware after next
- After the first middleware, Next
Open static Resources
Configure the static resource middleware and open the files in the static folder.
app.use(serve('static'))
Copy the code
A template engine
Ejs template engine
- Use the EJS template engine
// The template is an EJS file
// app.use(views('views', { extension: 'ejs' }))
// The template is an HTML file
app.use(views('views', { map: { html: 'ejs' }}))
Copy the code
2 templates
<! -- header.html -->
<h1>This is a header module</h1>
<! -- index.html -->
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Document</title>
<link rel="stylesheet" href="/css/base.css">
</head>
<body>
<p>Include () imports the HTML file, '-' and parses it</p>
<%- include('public/header.html') %>
<h1>Template engine - HTML</h1>
<h2><%=title%></h2>
<ul>
<%for(var i = 0; i < list.length; i++) {%>
<li><%=list[i]%></li>The < %} % ></ul>
<p>Public data configure ctx.state.userInfo in middleware -- <%= userInfo %></p>
<img src="/images/timg.jpg" alt="">
</body>
</html>
Copy the code
- Using a template engine
router.get('/'.async (ctx) => {
let title = 'Hello, EJs'
let arr = [111.222.333]
await ctx.render('index', {
title: title,
list: arr
})
})
Copy the code
Art-template template engine
- Introducing a template engine
render(app, {
root: path.join(__dirname, 'views'), // View position
extname: '.html'./ / suffix
debug: process.env.NODE_ENV ! = ='production' // Enable debugging mode
});
Copy the code
- The template
<! -- header.html -->
<h1>This is a header module</h1>
<! -- index.html -->
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Document</title>
<link rel="stylesheet" href="/css/base.css">
</head>
<body>
<h1>Template engine - Koa-art-template</h1>
<hr>
<h3>The child templates</h3>
{{include './public/header.html'}}
<h2>{{title}}</h2>
<hr>
<h3>cycle</h3>
<ul>
{{each arr}}
<li>{{$value}}</li>
{{/each}}
</ul>
<hr>
<h3>conditions</h3>
{{if num > 20}}
<strong>More than 20</strong>
{{else}}
<strong>Less than 20</strong>
{{/if}}
<hr>
<img src="/images/timg.jpg" alt="">
</body>
</html>
Copy the code
- Using a template engine
router.get('/'.async (ctx) => {
let title = 'Hello, art-template'
let arr = [111.222.333]
let num = 10
await ctx.render('index', { title, arr, num })
})
Copy the code
Use of cookies and sessions
The use of cookies
- Server setting cookie
router.get('/'.async (ctx) => {
// KoA does not support setting Chinese cookies directly
var userInfo = new Buffer('Joe').toString('base64')
ctx.cookies.set('userInfo', userInfo, {
maxAge: 1000 * 60 * 60.httpOnly: true.// True indicates that only the server can access the cookie. False indicates that both the client and server can access the cookie
})
await ctx.render('artIndex')})Copy the code
- Use cookies on the server
router.get('/news'.async (ctx) => {
var cookieData = ctx.cookies.get('userInfo')
var transformCookie = new Buffer(cookieData, 'base64').toString()
console.log('Get cookie information', transformCookie);
await ctx.render('news')})Copy the code
- The client obtains cookies
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Document</title>
</head>
<body>
<h2>News page</h2>
<script>
console.log(document.cookie)
</script>
</body>
</html>
Copy the code
HttpOnly: true: Cookies cannot be obtained via document.cookie on news. HTML pages. When httpOnly: false, a cookie can be obtained via document.cookie on the news. HTML page.
The use of the session
- The import file
const session = require('koa-session')
Copy the code
- Configuring session Middleware
app.keys = ['some secret hurr']; // Cookie signature
const CONFIG = {
key: 'koa.sess'./ * * * / by default
maxAge: 86400000.// Expiration time of cookie
autoCommit: true./ * * * /
overwrite: true./ * * * /
httpOnly: true./** true Only the server side can get cookies */
signed: true./** Default signature */
rolling: false./** Forcibly set the cookie on each request, which resets the cookie expiration time */
renew: true./** (boolean) renew session when session is nearly expired, so we can always keep user logged in. (default is false)*/
secure: false./** (boolean) secure cookie*/
sameSite: null./** (string) session cookie sameSite options (default null, don't set it) */
};
app.use(session(CONFIG, app));
Copy the code
- Set up the session
router.get('/login'.async (ctx) => {
/ / set the session
ctx.session.userInfo = 'the session information'
ctx.body = 'Login page'
})
Copy the code
- Access to the session
router.get('/'.async (ctx) => {
/ / get the session
console.log('Get Session info', ctx.session.userInfo);
await ctx.render('artIndex')})Copy the code
Using the mongodb database
The directory structure
Connect to mongodb database, complete add, delete, change and check function, use third-party plug-in “mongodb”: “^3.6.3”
- Views page file
- Home page index. HTML
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Document</title>
</head>
<body>
<h1>Template engine - Koa-art-template</h1>
<hr>
<a href="/user/add">increase</a>
<table>
<tr>
<th>The name</th>
<th>age</th>
<th>gender</th>
<th>state</th>
<th>operation</th>
</tr>
{{each list}}
<tr>
<td>{{$value.username}}</td>
<td>{{$value.age}}</td>
<td>{{$value.sex}}</td>
<td>{{$value.status}}</td>
<td><a href="/user/edit? id={{@$value._id}}">Modify the</a><a href="/user/delete? id={{@$value._id}}">delete</a></td>
</tr>
{{/each}}
</table>
</body>
</html>
Copy the code
- Add page add.html
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Document</title>
</head>
<body>
<h2>New Data Page</h2>
<form action="/user/doAdd" method="POST">User name:<input type="text" name="username">Age:<input type="text" name="age">Gender:<input type="text" name="sex">Status:<input type="text" name="status">
<input type="submit" value="Submit">
</form>
</body>
</html>
Copy the code
- Modify the page edit.html
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Document</title>
</head>
<body>
<h2>Edit data page</h2>
<form action="/user/doEdit" method="POST">
<input type="hidden" name="id" value="{{@list._id}}">User name:<input type="text" name="username" value="{{list.username}}">Age:<input type="text" name="age" value="{{list.age}}">Gender:<input type="text" name="sex" value="{{list.sex}}">Status:<input type="text" name="status" value="{{list.status}}">
<input type="submit" value="Submit">
</form>
</body>
</html>
Copy the code
- The module folder
It is used to connect to the database, encapsulate and export the method of adding, deleting, changing and checking
- Example Export the database configuration information – config.js
var app = {
dbUrl: 'mongodb://localhost:27017'.dbName: 'koa'
}
module.exports = app
Copy the code
- Encapsulate operation database method – db.js
const MongoClient = require('mongodb').MongoClient;
const ObjectID = require('mongodb').ObjectID
const Config = require('./config')
class Db {
// Use singleton multiple instances are not shared
static getInstance() {
if(! Db.instance) { Db.instance =new Db()
}
return Db.instance
}
constructor() {
this.dbClient = null
}
connect() {
return new Promise((resolve, reject) = > {
if (!this.dbClient) {
MongoClient.connect(Config.dbUrl, (err, client) = > {
if(err) {
reject(err)
}else {
var db = client.db(Config.dbName)
this.dbClient = db
resolve(this.dbClient)
}
})
}
else resolve(this.dbClient)
})
}
// find method find collection name find rule
find(collectionName, json) {
return new Promise((resolve, reject) = > {
this.connect().then((db) = > {
var result = db.collection(collectionName).find(json)
result.toArray((err, docs) = > {
if (err) reject(err)
resolve(docs)
})
})
})
}
// Update method Updates the updated data of the set name to be updated
update(collectionName, json1, json2) {
return new Promise((resolve, reject) = > {
this.connect().then(db= > {
db.collection(collectionName).updateOne(json1, {
$set: json2
}, (err, result) = > {
if(err) reject(err)
resolve(result)
})
})
})
}
// The insert method inserts the data that the collection name inserts
insert(collectionName, json) {
return new Promise((resolve, reject) = > {
this.connect().then((db) = > {
db.collection(collectionName).insertOne(json, (err, result) = > {
if(err) reject(err)
resolve(result)
})
})
})
}
// Delete method Delete collection name delete field
remove(collectionName, json) {
return new Promise((resolve, reject) = > {
this.connect().then((db) = > {
db.collection(collectionName).removeOne(json, (err, result) = > {
if(err) reject(err)
resolve(result)
})
})
})
}
// Based on the returned ID, generate the style ID required by mongodb
getObjectId(id) {
return new ObjectID(id)
}
}
module.exports = Db.getInstance()
Copy the code
- The router file
- User Route configuration user.js
var Router = require('koa-router')
var DB = require('.. /module/db')
var userRouter = new Router()
// Configure the route
userRouter.get('/'.async (ctx) => {
var result = await DB.find('user', {})
await ctx.render('artIndex', {list: result})
})
userRouter.get('/add'.async (ctx) => {
await ctx.render('add')
})
userRouter.post('/doAdd'.async (ctx) => {
let addData = ctx.request.body
const result = await DB.insert('user', addData)
try {
if (result.result.ok) {
ctx.redirect('/user')}}catch (error) {
ctx.redirect('/user/add')
}
})
userRouter.get('/edit'.async (ctx) => {
// Get user information based on id
let userId = ctx.query.id
const result = await DB.find('user', { "_id": DB.getObjectId(userId) })
await ctx.render('edit', {list: result[0]})
})
userRouter.post('/doEdit'.async (ctx) => {
let userData = ctx.request.body
var id = userData.id
var username = userData.username
var age = userData.age
var sex = userData.sex
var status = userData.status
const result = await DB.update('user', {"_id": DB.getObjectId(id)}, { username, age, sex, status })
try {
if (result.result.ok) {
ctx.redirect('/user')}}catch (error) {
ctx.redirect('/user/add')
}
})
userRouter.get('/delete'.async (ctx) => {
let id = ctx.query.id
const result = await DB.remove('user', { "_id": DB.getObjectId(id) })
try {
if (result.result.ok) {
ctx.redirect('/user')}}catch (error) {
}
})
module.exports = userRouter
Copy the code
- Router.js is configured under the primary route
var Router = require('koa-router')
var router = new Router()
var userRouter = require('./user')
// Configure child routes and start routes
router.use('/user', userRouter.routes())
module.exports = router
Copy the code
- Entry file app.js
var Koa = require('koa');
var bodyParser = require('koa-bodyparser');
const render = require('koa-art-template');
const path = require('path');
var router = require('./router/router');
var app = new Koa()
// Parse post request data
app.use(bodyParser())
// ! art-template
render(app, {
root: path.join(__dirname, 'views'), // View position
extname: '.html'./ / suffix
debug: process.env.NODE_ENV ! = ='production' // Enable debugging mode
});
// todo starts the route
app
.use(router.routes())
.use(router.allowedMethods())
app.listen(3001)
Copy the code