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:路由
- 安装使用
使用 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:模板引擎
- 安装使用
npm i koa-swig const Swig = require('koa-swig') const render = Swig(options)
- 加载 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(模板文件, 数据)
- 模板语法
输出:{{表达式}}
判断
{% 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解析、数据提交
- 安装
npm i koa-bodyparser
- 使用
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解析、文件上传
- 安装
npm i koa-multer
- 使用
const multer = require('koa-multer') const uploader = multer(opts) router.post('/upload',uploader.signle('avatar')) opts: dest / storage: 存放上传文件的目录 fileFilter:过滤上传文件函数 preservePath:是否保留文件的完整路径
- 单文件上传
.single(fieldName):接收一个指定fieldName的文件上传,上传后的数据保存在 req.file 下 file 细节 - fieldname:上传中的字段名 - originalname:源文件名称 - mimetype:文件MIME类型 - size:文件大小 - destination:文件存储在服务器中文件夹 - filename:文件存储在服务器中的名称 - path:文件存储在服务器中的完整路径
- 批量上传
- .array(fieldName[, maxCount]):接收一个指定fieldName的上传数组,上传后的数据保存在 req.files 下,maxCount 用于指定最大上传数量 {name:'',maxCount:2} - .fields(fields):接收批量的非同组(.array为同组模式)的上传,上传后的数据保存在 req.files下 [{name:'',maxCount:2},{...}]
- 自定义存储
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 })
- 上传过滤
function fileFilter (req, file, cb) { //未通过 cb(null, false) //通过 cb(null, true) //错误 cb(new Error('不能上传'))
- 错误处理
app.post('/profile', function (req, res) { const avatarUploader = uploader.signle('avatar') avatarUploader(req, res, function (err) { if (err) {return} }) })