--基于Node.js平台的下一代web开发框架
简介
- Koa是一个新的web框架,是Express的升级版。通过利用async函数,Koa帮你丢弃回调函数,能有力地增强错误处理。Koa 并没有捆绑任何中间件,而是提供了一套方法,能够快速地编写服务端应用程序。
安装
!! 注意:koa依赖node v7.6.0或ES2015及更高版本和async方法支持
配置
- $ npm install 7
- $ npm i koa
- $ node my-koa-app.js
应用程序
- Koa应用程序是一个包含一组中间件函数的对象,它按类似堆栈的方式组织和执行,它其中的一个关键点在于其低级中间件层中提供高级'语法糖'。(个人理解是封装了很多中间件的使用函数,并没有引入那些中间件)
const Koa=require('koa');
const app=new Koa();
app.use(async ctx=>{ //ctx是request,response,next的集合体
ctx.body='hello world';
});
app.listen(3000); //app.listen()跟epxress中listen()的使用相同
级联
-
Koa 中间件以更传统的方式级联,之前难以使用 node 的回调,然而使用 async 功能,可以实现 “真实” 的中间件。对比 Connect 的实现,通过一系列功能直接传递控制,直到一个返回,Koa 调用“下游”,然后控制流回“上游”。
-
下面以 “Hello World” 的响应作为示例,当请求开始时首先请求流通过 x-response-time 和 logging 中间件,然后继续移交控制给 response 中间件。当一个中间件调用 next() 则该函数暂停并将控制传递给定义的下一个中间件。当在下游没有更多的中间件执行后,堆栈将展开并且每个中间件恢复执行其上游行为。
const Koa = require('koa');
const app = new Koa();
// logger
//anync->await用法就是ES6的Generator的语法糖
app.use(async (ctx, next) => {
await next(); //到这里暂停,执行下一个中间件
const rt = ctx.response.get('X-Response-Time');
console.log(`${ctx.method} ${ctx.url} - ${rt}`);
});
// x-response-time
app.use(async (ctx, next) => {
const start = Date.now();
await next(); //到这里暂停,执行下一个中间件
const ms = Date.now() - start;
ctx.set('X-Response-Time', `${ms}ms`);
});
// response
app.use(async ctx => {
ctx.body = 'Hello World';
});
//主线程里中间件执行完,执行顺序变成'回流'由下往上执行await next()后面的内容
app.listen(3000);
设置
-
应用程序设置是app实例上的属性,目前支持这些
- app.env 默认是NODE_ENV或"development"
- 这里打印console.log(app);
- 得到的是一个对象 { subdomainOffset : 2 , proxy : false , env : 'development' }
- domain是域名的意思,subdomainOffset我觉得应该是端口有几个的意思,毕竟下面有说app.listen()可以重复使用开启多个端口
- proxy:false指的是代理,false表示代理没开,前端的代理指的是解决跨域问题
- env表示环境,目前是开发环境
- 开发环境 代码开发阶段所处的环境
- 生成环境 开发阶段的代码经过编译,压缩后文件运行的环境
- 测试环境 开发阶段的代码经过编译,压缩后文件进行代码质量检测,语法检测
- 上线环境 处理后放在服务器或主机中运行
- app.keys 签名的cookie密钥数组
- app.proxy 当真正的代理头字段被信任时 //应该是代理或者转发的意思
- app.subdomainOffset对于要忽略的.subdomains偏移[2] //这句话没看懂
- app.env 默认是NODE_ENV或"development"
-
可以将设置传递给构造函数
const Koa=require('koa');
const app=new Koa({proxy:true});
- 或者动态的
const Koa = require('koa');
const app = new Koa();
app.proxy = true;
-
app.listen(...)
- Koay应用程序不是HTTP服务器1对1展现,可以将一个或多个Koa应用程序安装在一起以形成具有单个HTTP服务器的更大应用程序
//其实就是可以放多个的意思,一个js文件创建多个端口,这些可以通过请求不同端口访问设置相同的响应 app.listen(3000); app.listen(3001); app.listen(3002); //上面的app.listen(...)方法只是下面的语法糖 const http = require('http'); const Koa = require('koa'); const app = new Koa(); http.createServer(app.callback()).listen(3000); //httph和https请求都可以设置 -
app.callback()
- 返回适用于 http.createServer()方法的回调函数来处理请求。你也可以使用此回调函数将 koa 应用程序挂载到 Connect/Express 应用程序中。
-
app.use(function)
- 将给定的中间件方法添加到此应用程序,详情记得查阅手册
-
app.keys=
- 设置签名的Cookie密钥
- 这些被传递给KeyGrip,但是也可以传递自己的KeyGrip实例
app.keys = ['im a newer secret', 'i like turtle']; app.keys = new KeyGrip(['im a newer secret', 'i like turtle'], 'sha256');- 这些密钥可以倒换,并在使用{signed:true}参数签名Cookie时使用
ctx.cookies.set('name','tobi',{signed:true}); -
app.context
- app.context是从其创建ctx的原型。可以通过编辑app.context为 ctx 添加其他属性。这对于将ctx添加到整个应用程序中使用的属性或方法非常有用,这可能会更加有效(不需要中间件)和/或 更简单(更少的require()),而更多地依赖于ctx,这可以被认为是一种反模式
app.context.db=db(); app.use(async ctx=>{ console.log(ctx.db); })- 注意:安装的应用程序目前使用其父级的 ctx和设置,这就是之前说的一组中间件 github.com/koajs/koa/i…
-
错误处理
- 默认情况下,将所有错误输出到stderr,除非app.silent为true,当err.status是404或err.expose是true时默认错误处理程序也不会输出错误。要执行自定义错误处理逻辑,如集中式日志记录,可以添加一个'error'事件侦听器
app.on('error',err=>{ log.error('server error',err); })- 如果req/res期间出现错误,并且无法响应客户端,Context实例仍然被传递
app.on('error',(err,ctx)=>{ log.error('server error',err,ctx); })- 当发生错误,但是可以响应客户端时,也没有数据被写入socket中,Koa将用一个500"内部服务器错误"进行适当的响应,在任意情况下,为了记录目的,都会发出应用级错误
上下文(Context)
- KoaContext将node的request和response对象封装到单个对象中,为编写Web应用程序和API提供了许多有用的方法,这些操作在HTTP服务器开发中频繁使用,他们被添加到此级别而不是更高级别的框架,这将强制中间件重新实现此通用功能
- 每个请求都将创建一个Context,并在中间件中作为接收器引用,或者ctx标识符
app.use(async ctx =>{
ctx; //这是Context
ctx.request;//这是koa Request
ctx.response;//这是koa Response
})
- 为方便起见许多上下文的访问器和方法直接委托给它们的 ctx.request或 ctx.response ,不然的话它们是相同的。 例如 ctx.type 和 ctx.length 委托给 response 对象,ctx.path 和 ctx.method 委托给 request。
API
-
ctx.req -> node的request对象
-
ctx.res -> node的response对象
- 这里有说避免使用node的
- res.statusCode
- res.writeHead()
- res.write()
- res.end()
-
ctx.state 推荐的命名空间,用于通过中间件传递信息和你的前端视图
- ctx.state.user = await User.find(id); //数据库查询,没看懂是想表达什么意思
-
ctx.app.emit()
- Koa制定的事件触发方法,自定义事件用的就是node.js的自定义事件方法,emit方法也是延续的node.js的events模块的方法
ctx.app.on('aa',function(){ console.log('hello word'); }); ctx.app.emit('aa'); -
ctx.cookies.get(name,[options])
- 通过options 获取cookie的name,signed所请求的cookie应该被签名,koa使用cookies模块,其中只需传递参数
-
ctx.cookies.set(name,value,[options])
- 通过options 设置cookie name的value
- maxAge一个数字表示从Date.now()得到的毫秒数
- signed cookie签名值
- expires cookie国企的Date
- path cookie路径,默认是'/'
- domain cookie域名
- secure 安全 cookie
- httpOnly 服务器可访问 cookie, 默认是 true
- overwrite 一个布尔值,表示是否覆盖以前设置的同名的 cookie (默认是 false). 如果是 true, 在同一个请求中设置相同名称的所有 Cookie(不管路径或域)是否在设置此Cookie 时从 Set-Cookie 标头中过滤掉。