Koa

一、安装与载入

npm i koa

载入

    const koa = require('koa')
    const app = new koa()
    app.listen(80)
响应输出
    app.use(async ctx => {ctx.body = 'Hello'})
// 热重载:  supervisor
全局下载:npm i -g supervisor
// npm i supervisor

使用:supervisor app.js

二、Application对象

  • 当前应用程序对象,即 new Koa() 得到的实例对象,保存了应用全局状态以及其他对象,
  • 子对象
    Context
    Request
    Response

context 对象

  • 每一次请求都会包装一个 context 对象
  • 该对象对 node 的 request 和 response 对象进行了封装(加强了node中的request和response)
  • 同时提供了其他一些有用的 api
  • koa 会把 context 传入到中间件函数的第一个参数中
  • 可以对context进行扩展,并在中间件中使用
    .req:Node 的 request 对象
    .res:Node 的 response 对象
        注意:在 Koa 中尽量使用Koa提供的封装对象
    .request:Koa 的 request 对象
    .response:Koa 的 response 对象
    .state:用户数据存储空间
    .app:当前应用程序实例 - Application 对象
.cookies 对象
    .get(name, [options])
    .set(name, value, [options])
    options
        .maxAge    - .signed
        .expires    - .path
        .domain    - .secure
        .httpOnly    - .overwrite
    .throw([status][, msg][, properties])
抛出一个错误,Koa 会进行处理(比如返回对应的响应信息)
在app.on('error')事件中可以捕获到该异常,error 参数中也会保存msg和properties
Request 对象
  • 注:在 Koa 中,request 对象是 Context 对象下的一个属性,为了方便调用 request 对象下的一些常用属性与方法同时在 Context 下有对应的挂载,也就是 Context 下的一些属性与方法等同于 request 对象下的对应属性和方法,response也是如此
.header:头信息对象,别名:headers
.header=:设置头信息,别名:headrs=
.method:请求方法
.method=:设置请求方法
.length:请求正文内容长度
.url:请求URL
.url=:设置请求URL,不包含协议与主机部分
.orginalURL:原始URL,不包含协议与主机部分

.href:原始完整URL,包含协议、主机、请求串
.path:URL路径部分
.path=:设置URL路径
.querystring:URL中的querystring
.querystring=:设置URL中的querystring
.search:URL中的search,带 ? 的querystring
.search=:设置URL中的search

.host:请求头中的host
.hostname:请求头中的hostname
.URL:解析过的URL对象
.type:请求头中 content-type
.charset:请求头中的charset
.query:解析过的querystring对象
.query=:设置querystring对象值

.fresh:判断缓存设置时候有效,true表示有效
.stale:与fresh相反

.protocol:请求使用的协议
.secure:是否是安全协议,protocol=='https'
.ip:请求客户端 IP
.ips:请求客户端所有 IP(比如使用了代理等)
.subdomains:子域名数组
.is(types...):判断提交内容的MIME类型

.socket:request.socket对象
.get(field):获取请求头的通用方法
Response 对象
.header:响应头对象
.headers:header的别名
.socket:response.socket对象
.status:响应状态码
.status=:设置响应状态码
.message:响应状态码描述文本
.message=:设置响应状态码描述文本

.body:响应内容
.body=:设置响应内容,如果status没有设置,Koa会默认设置status为:200 或者 204,同时 Koa 会根据返回的数据类型自动设置 content-type
    string:text/html 或 text/plain
    buffer/Stream:application/octet-stream
    object:application/json

.length:响应内容长度
.length=:设置响应内容长度
.get(field):获取指定头信息
.get(fields):批量设置头信息
.set(field):设置指定头信息
.append(field, value):追加头信息
.remove(field):移除头信息

.type:获取 content-type
.type=:设置 content-type
.is(types...):判断 content-type

.redirect(url):重定向,默认重定向状态码为:302,可以通过status进行设置
.attachment([filename]):设置下载文件头,filename为下载文件的名称

三、中间件

1.koa-static-cache:静态文件代理服务

const koaStaticCache = require('koa-static-cache')
app.use(staticCache(dir [, options] [, files])
        dir:服务器上存放静态资源的目录
        options:选项设置
            prefix:URL前缀,默认是 '.'
            maxAge:缓存时间,单位毫秒,默认为0
            gzip:启用gzip压缩传输,默认为true
        files:合并的文件对象)

2.koa-router:路由

  1. 安装使用
    使用
        const Router = require('koa-router')
        const router = new Router()


        .get|put|post|patch|delete|del|all
    实例
        router.get( '/', (ctx, next) => {} )
        通过 get 方法访问 '/' 的时候执行注册的函数

        给应用注册指定的路由中间件
            .use([path], middleware)

            app.use(router.routes())

    命名路由
            router.get('main', '/', cb);
    复合中间件
            router.get('/', cb1, cb2, cb3...)
                注意调用中间件的next函数

    嵌套路由
            const parent = new Router()
            const child = new Router()
            parent.use('/p', child.routes())
    路由前缀
            const router = new Router({
                prefix: '/user'
            })

    动态路由
            router.get('/user/:id', cb);
            动态路由参数通过 ctx.params 对象获取
    路由重定向
            router.redirect('/user', '/login', 301)
    URL生成器
            Router.url('/list', {page:1}, {query{order:'desc'}}) 生成:/list/1?order=desc

3.koa-swig:模板引擎

  1. 安装使用
        npm i koa-swig
        const Swig = require('koa-swig')
        const render = Swig(options)
  1. 加载 co 模块
  • koa v2.x 需要使用 co 函数
    npm i co
    const co = require('co')
    把渲染方法挂载到 Context 下
    app.context.render = co.wrap( render(opts) )
        opts:
        root: 模板存放目录
        autoescape:是否自动 html 编码转换//一般默认是不自动转换,设置为true
        cache:是否启用缓存 // 属性:memory:把解析后的模板保存在硬盘,适用于线上模式
        ext:模板后缀,'html'
数据渲染:
    render & data
    ctx.body = await ctx.render(模板文件, 数据)
  1. 模板语法
            输出:{{表达式}}

判断

            {% if 条件 %}{% endif %}
            {% if 条件 %}{%elseif 条件%}{% endif %}
            {% if 条件 %} {%else%}{% endif %}

循环

            {% for x in y %}{% endfor %}
            {%for key, val in data%}
          内置变量
                loop.index:从1计算
                loop.index0:从0计算
                loop.length:长度

继承

        {% extends "base.html" %}
        {% block name %}{% endblock %}
          类似类的方法,子模板可以重写

包含导入

          {% include 'widget.html' %}
        变量设置与传参
          {% set name = 'zMouse' %}
          {% include 'widget.html' with name %}
          在使用 include 的模板中可以使用 name

4.koa-bodyparser:body解析、数据提交

  1. 安装
        npm i koa-bodyparser
  1. 使用
        const bodyParser = require('koa-bodyparser')
        app.use( bodyParser([opts]) )
        该中间件会在解析来自正文的数据以后,把解析后的数据挂载在ctx.request.body下面
        opts:
        - enableTypes: 允许解析的类型,['json', 'form']
        - encoding:编码,默认 utf-8
        - formLimit:urlencode 编码类型数据的最大size,默认 56kb
        - jsonLimit:json 格式数据最大size,默认 1mb
        - textLimit:文本格式数据最大size,默认 1mb
        - strict:是否是严格默认,json只接受数组和对象        

5.koa-multer:formData解析、文件上传

  1. 安装
        npm i koa-multer
  1. 使用
        const multer = require('koa-multer')
        const uploader = multer(opts)
        router.post('/upload',uploader.signle('avatar'))
        opts:
            dest / storage: 存放上传文件的目录
            fileFilter:过滤上传文件函数
            preservePath:是否保留文件的完整路径    
  1. 单文件上传
        .single(fieldName):接收一个指定fieldName的文件上传,上传后的数据保存在 req.file 下
        file 细节
        - fieldname:上传中的字段名
        - originalname:源文件名称
        - mimetype:文件MIME类型
        - size:文件大小
        - destination:文件存储在服务器中文件夹
        - filename:文件存储在服务器中的名称
        - path:文件存储在服务器中的完整路径
  1. 批量上传
        - .array(fieldName[, maxCount]):接收一个指定fieldName的上传数组,上传后的数据保存在 req.files 下,maxCount 用于指定最大上传数量
            {name:'',maxCount:2}
        - .fields(fields):接收批量的非同组(.array为同组模式)的上传,上传后的数据保存在 req.files下
            [{name:'',maxCount:2},{...}]
  1. 自定义存储
        const storage = multer.diskStorage({
              destination: function (req, file, cb) {
                    cb(null, '/tmp/my-uploads')
              },
              filename: function (req, file, cb) {
                    cb(null, file.fieldname + '-' + Date.now())
              }
        })
        uploader = multer({ storage: storage })
  1. 上传过滤
function fileFilter (req, file, cb) {
      //未通过
    cb(null, false)
      //通过
      cb(null, true)
      //错误
    cb(new Error('不能上传'))
  1. 错误处理
        app.post('/profile', function (req, res) {
            const avatarUploader = uploader.signle('avatar')

            avatarUploader(req, res, function (err) {
        if (err) {return}
    })
})