• 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>

    <未完>

  • 相关阅读:
    ACL2016信息抽取与知识图谱相关论文掠影
    决策树之信息与熵的计算
    从零开始一个http服务器(六)-多路复用和压力测试
    从零开始一个http服务器(三)-返回response 构造
    从零开始一个http服务器(二)-请求request解析
    从零开始一个http服务器(一)-开始
    从零开始一个http服务器(五)-模拟cgi
    从零开始一个http服务器(四)-动态返回
    拼音转汉字
    24点牌 递归算法
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12256312.html
Copyright © 2020-2023  润新知