Koa 学习


中间件引擎

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
const Koa = require('koa');
let app = new Koa();

const middleware1 = async (ctx, next) => {
console.log(1);
await next();
console.log(6);
}

const middleware2 = async (ctx, next) => {
console.log(2);
await next();
console.log(5);
}

const middleware3 = async (ctx, next) => {
console.log(3);
await next();
console.log(4);
}

app.use(middleware1);
app.use(middleware2);
app.use(middleware3);
app.use(async(ctx, next) => {
ctx.body = 'hello world'
})

app.listen(3001)


// 控制台会出现以下结果
// 1
// 2
// 3
// 4
// 5
// 6

路由

koa原生路由的实现

ctx.request.path

1
2
3
4
5
6
7
8
const main = ctx => {
if (ctx.request.path !== '/') {
ctx.response.type = 'html';
ctx.response.body = '<a href="/">Index Page</a>';
} else {
ctx.response.body = 'Hello World';
}
};

koa 路由组件

1、安装

install --save koa-router@7```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

2、快速使用koa-router


```js
const route = require('koa-route');

const about = ctx => {
ctx.response.type = 'html';
ctx.response.body = '<a href="/">Index Page</a>';
};

const main = ctx => {
ctx.response.body = 'Hello World';
};

app.use(route.get('/', main));
app.use(route.get('/about', about));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
const Koa = require('koa')
const fs = require('fs')
const app = new Koa()

const Router = require('koa-router')

let home = new Router()

// 子路由1
home.get('/', async ( ctx )=>{
let html = `
<ul>
<li><a href="/page/helloworld">/page/helloworld</a></li>
<li><a href="/page/404">/page/404</a></li>
</ul>
`
ctx.body = html
})

// 子路由2
let page = new Router()
page.get('/404', async ( ctx )=>{
ctx.body = '404 page!'
}).get('/helloworld', async ( ctx )=>{
ctx.body = 'helloworld page!'
})

// 装载所有子路由
let router = new Router()
router.use('/', home.routes(), home.allowedMethods())
router.use('/page', page.routes(), page.allowedMethods())

// 加载路由中间件
app.use(router.routes()).use(router.allowedMethods())

app.listen(3000, () => {
console.log('[demo] route-use-middleware is starting at port 3000')
})

数据请求

get 请求数据

在koa中,获取GET请求数据源头是koa中request对象中的query方法或querystring方法,query返回是格式化好的参数对象,querystring返回的是请求字符串,由于ctx对request的API有直接引用的方式,所以获取GET请求数据有两个途径。

1.是从上下文中直接获取

  • 请求对象ctx.query,返回如 { a:1, b:2 }
  • 请求字符串 ctx.querystring,返回如 a=1&b=2
    2.是从上下文的request对象中获取
  • 请求对象ctx.request.query,返回如 { a:1, b:2 }
  • 请求字符串 ctx.request.querystring,返回如 a=1&b=2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const Koa = require('koa')
const app = new Koa()

app.use( async ( ctx ) => {
let url = ctx.url
// 从上下文的request对象中获取
let request = ctx.request
let req_query = request.query
let req_querystring = request.querystring

// 从上下文中直接获取
let ctx_query = ctx.query
let ctx_querystring = ctx.querystring

ctx.body = {
url,
req_query,
req_querystring,
ctx_query,
ctx_querystring
}
})

app.listen(3000, () => {
console.log('[demo] request get is starting at port 3000')
})

post 请求

koa-bodyparser中间件

对于POST请求的处理,koa-bodyparser中间件可以把koa2上下文的formData数据解析到ctx.request.body中

安装koa2版本的koa-bodyparser@3中间件

install --save koa-bodyparser@3```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44






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

// 使用ctx.body解析中间件
app.use(bodyParser())

app.use( async ( ctx ) => {

if ( ctx.url === '/' && ctx.method === 'GET' ) {
// 当GET请求时候返回表单页面
let html = `
<h1>koa2 request post demo</h1>
<form method="POST" action="/">
<p>userName</p>
<input name="userName" /><br/>
<p>nickName</p>
<input name="nickName" /><br/>
<p>email</p>
<input name="email" /><br/>
<button type="submit">submit</button>
</form>
`
ctx.body = html
} else if ( ctx.url === '/' && ctx.method === 'POST' ) {
// 当POST请求的时候,中间件koa-bodyparser解析POST表单里的数据,并显示出来
let postData = ctx.request.body
ctx.body = postData
} else {
// 其他请求显示404
ctx.body = '<h1>404!!! o(╯□╰)o</h1>'
}
})

app.listen(3000, () => {
console.log('[demo] request post is starting at port 3000')
})
大专栏  Koa 学习/>

加载静态资源

使用koa-static中间件

1
2
3
4
5
const path = require('path');
const serve = require('koa-static');

const main = serve(path.join(__dirname));
app.use(main);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const Koa = require('koa')
const path = require('path')
const static = require('koa-static')

const app = new Koa()

// 静态资源目录对于相对入口文件index.js的路径
const staticPath = './static'

app.use(static(
path.join( __dirname, staticPath)
))


app.use( async ( ctx ) => {
ctx.body = 'hello world'
})

app.listen(3000, () => {
console.log('[demo] static-use-middleware is starting at port 3000')
})

重定向

有些场合,服务器需要重定向(redirect)访问请求。比如,用户登陆以后,将他重定向到登陆前的页面。ctx.response.redirect()方法可以发出一个302跳转,将用户导向另一个路由。

1
2
3
4
5
6
const redirect = ctx => {
ctx.response.redirect('/');
ctx.response.body = '<a href="/">Index Page</a>';
};

app.use(route.get('/redirect', redirect));

使用cookie/session

koa提供了从上下文直接读取、写入cookie的方法

  • ctx.cookies.get(name, [options]) 读取上下文请求中的cookie
  • ctx.cookies.set(name, value, [options]) 在上下文中写入cookie
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const Koa = require('koa')
const app = new Koa()

app.use( async ( ctx ) => {

if ( ctx.url === '/index' ) {
ctx.cookies.set(
'cid',
'hello world',
{
domain: 'localhost', // 写cookie所在的域名
path: '/index', // 写cookie所在的路径
maxAge: 10 * 60 * 1000, // cookie有效时长
expires: new Date('2017-02-15'), // cookie失效时间
httpOnly: false, // 是否只用于http请求中获取
overwrite: false // 是否允许重写
}
)
ctx.body = 'cookie is ok'
} else {
ctx.body = 'hello world'
}

})

app.listen(3000, () => {
console.log('[demo] cookie is starting at port 3000')
})

koa2原生功能只提供了cookie的操作,但是没有提供session操作。session就只用自己实现或者通过第三方中间件实现。在koa2中实现session的方案有以下几种:

  • 如果session数据量很小,可以直接存在内存中
  • 如果session数据量很大,则需要存储介质存放session数据

数据库存储方案
将session存放在MySQL数据库中

需要用到中间件

  • koa-session-minimal 适用于koa2 的session中间件,提供存储介质的读写接口 。
  • koa-mysql-session 为koa-session-minimal中间件提供MySQL数据库的session数据读写操作。

将sessionId和对于的数据存到数据库

  • 将数据库的存储的sessionId存到页面的cookie中
  • 根据cookie的sessionId去获取对于的session信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
const Koa = require('koa')
const session = require('koa-session-minimal')
const MysqlSession = require('koa-mysql-session')

const app = new Koa()

// 配置存储session信息的mysql
let store = new MysqlSession({
user: 'root',
password: 'abc123',
database: 'koa_demo',
host: '127.0.0.1',
})

// 存放sessionId的cookie配置
let cookie = {
maxAge: '', // cookie有效时长
expires: '', // cookie失效时间
path: '', // 写cookie所在的路径
domain: '', // 写cookie所在的域名
httpOnly: '', // 是否只用于http请求中获取
overwrite: '', // 是否允许重写
secure: '',
sameSite: '',
signed: '',

}

// 使用session中间件
app.use(session({
key: 'SESSION_ID',
store: store,
cookie: cookie
}))

app.use( async ( ctx ) => {

// 设置session
if ( ctx.url === '/set' ) {
ctx.session = {
user_id: Math.random().toString(36).substr(2),
count: 0
}
ctx.body = ctx.session
} else if ( ctx.url === '/' ) {

// 读取session信息
ctx.session.count = ctx.session.count + 1
ctx.body = ctx.session
}

})

app.listen(3000)
console.log('[demo] session is starting at port 3000')

模板引擎加载

安装模板

install --save koa-views```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

### 使用模板

目录结构:

├── package.json
├── index.js
└── view
└── index.ejs

### ./index.js 下配置:


```js
const Koa = require('koa')
const views = require('koa-views')
const path = require('path')
const app = new Koa()

// 加载模板引擎
app.use(views(path.join(__dirname, './view'), {
extension: 'ejs'
}))

app.use( async ( ctx ) => {
let title = 'hello koa2'
await ctx.render('index', {
title,
})
})

app.listen(3000)

./view/index.ejs 模板

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
</head>
<body>
<h1><%= title %></h1>
<p>EJS Welcome to <%= title %></p>
</body>
</html>

<未完>

原文地址:https://www.cnblogs.com/lijianming180/p/12256312.html