在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:guo-yu/koa-guide开源软件地址:https://github.com/guo-yu/koa-guide开源编程语言:开源软件介绍:中文文档Koa,下一代 Node.js web 框架 koa 简介由 Express 原班人马打造的 koa,致力于成为一个更小、更健壮、更富有表现力的 Web 框架。使用 koa 编写 web 应用,通过组合不同的 generator,可以免除重复繁琐的回调函数嵌套,并极大地提升常用错误处理效率。Koa 不在内核方法中绑定任何中间件,它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手。 安装 koaKoa需要支持ES2015和 您可以使用喜欢的依赖管理工具快速安装支持的node版本: $ nvm install 7
$ npm i koa
$ node my-koa-app.js 使用Babel来支持Async Functions在node 7.6版本以下,如果你想在koa里使用
你至少要使用transform-async-to-generator or transform-async-to-module-method插件,
来解析和转译async functions。例如,你可以在你的 {
"plugins": ["transform-async-to-generator"]
} 你也可以在env preset里使用目标选项 应用(Application)一个 Koa Application(以下简称 app)由一系列 generator 中间件组成。按照编码顺序在栈内依次执行,从这个角度来看,Koa app 和其他中间件系统(比如 Ruby Rack 或者 Connect/Express )没有什么太大差别,不过,从另一个层面来看,Koa 提供了一种基于底层中间件编写「语法糖」的设计思路,这让设计中间件变得更简单有趣。 在这些中间件中,有负责内容协商(content-negotation)、缓存控制(cache freshness)、反向代理(proxy support)与重定向等等功能的常用中间件(详见 中间件 章节),但如前所述, Koa 内核并不会打包这些中间件,让我们先来看看 Koa 极其简单的 Hello World 应用程序: var koa = require('koa');
var app = new koa();
app.use(function *(){
this.body = 'Hello World';
});
app.listen(3000); 如果使用Koa 2的话: var Koa = require('koa');
var app = new Koa();
app.use(ctx => {
ctx.body = 'Hello World';
});
app.listen(3000); 译者注: 与普通的 function 不同,generator functions 以 级联代码(Cascading)Koa 中间件以一种非常传统的方式级联起来,你可能会非常熟悉这种写法。 在以往的 Node 开发中,频繁使用回调不太便于展示复杂的代码逻辑,在 Koa 中,我们可以写出真正具有表现力的中间件。与 Connect 实现中间件的方法相对比,Koa 的做法不是简单的将控制权依次移交给一个又一个的中间件直到程序结束,Koa 执行代码的方式有点像回形针,用户请求通过中间件,遇到 下边这个例子展现了使用这一特殊方法书写的 Hello World 范例:一开始,用户的请求通过 x-response-time 中间件和 logging 中间件,这两个中间件记录了一些请求细节,然后「穿过」 response 中间件一次,最终结束请求,返回 「Hello World」。 当程序运行到 var koa = require('koa');
var app = koa();
// x-response-time
app.use(function *(next){
// (1) 进入路由
var start = new Date;
yield next;
// (5) 再次进入 x-response-time 中间件,记录2次通过此中间件「穿越」的时间
var ms = new Date - start;
this.set('X-Response-Time', ms + 'ms');
// (6) 返回 this.body
});
// logger
app.use(function *(next){
// (2) 进入 logger 中间件
var start = new Date;
yield next;
// (4) 再次进入 logger 中间件,记录2次通过此中间件「穿越」的时间
var ms = new Date - start;
console.log('%s %s - %s', this.method, this.url, ms);
});
// response
app.use(function *(){
// (3) 进入 response 中间件,没有捕获到下一个符合条件的中间件,传递到 upstream
this.body = 'Hello World';
});
app.listen(3000); 在上方的范例代码中,中间件依次被执行的顺序已经在注释中标记出来。你也可以自己尝试运行一下这个范例,并打印记录下各个环节的输出与耗时。 译者注: 「级联」这个词许多人也许在 CSS 中听说过,如果你不能理解为什么在这里使用这个词,可以将这种路由结构想象成 LESS 的继承嵌套书写方式:
上方的伪代码中标注了中间件的执行顺序,看起来是不是有点像 ruby 执行代码块(block)时 yield 的表现了?也许这能帮助你更好的理解 koa 运作的方式。 译者注: 更加形象的图可以参考 Django Middleware 应用配置(Settings)应用的配置是 app 实例的属性。目前来说,Koa 的配置项如下:
中间件(Middleware)
常用方法app.listen(...)用于启动一个服务的快捷方法,以下范例代码在 3000 端口启动了一个空服务: var koa = require('koa');
var app = koa();
app.listen(3000); app.listen 是 http.createServer 的简单包装,它实际上这样运行: var http = require('http');
var koa = require('koa');
var app = koa();
http.createServer(app.callback()).listen(3000); 如果有需要,你可以在多个端口上启动一个 app,比如同时支持 HTTP 和 HTTPS: var http = require('http');
var https = require('https');
var koa = require('koa');
var app = koa();
http.createServer(app.callback()).listen(3000);
https.createServer(app.callback()).listen(3001); app.callback()返回一个可被 app.use(function)将给定的 function 当做中间件加载到应用中,详见 中间件 章节 app.keys=设置一个签名 Cookie 的密钥。这些参数会被传递给 KeyGrip 如果你想自己生成一个实例,也可以这样: app.keys = ['im a newer secret', 'i like turtle'];
app.keys = new KeyGrip(['im a newer secret', 'i like turtle'], 'sha256'); 注意,签名密钥只在配置项 this.cookies.set('name', 'tobi', { signed: true }); 错误处理(Error Handling)除非 app.on('error', function(err){
log.error('server error', err);
}); 当任何 app.on('error', function(err, ctx){
log.error('server error', err, ctx);
}); 任何错误有可能被回应到客户端,比如当没有新数据写入 socket 时,Koa 会默认返回一个 500 错误,并抛出一个 app 级别的错误到日志处理中间件中。 应用上下文(Context)Koa 的上下文封装了 request 与 response 对象至一个对象中,并提供了一些帮助开发者编写业务逻辑的方法。为了方便,你可以在 每一个请求都会创建一段上下文。在控制业务逻辑的中间件中,上下文被寄存在 app.use(function *(){
this; // 上下文对象
this.request; // Request 对象
this.response; // Response 对象
}); 为了使用方便,许多上下文属性和方法都被委托代理到他们的 Request 对象ctx.request 对象包括以下属性和别名方法,详见 Request 章节
Response 对象ctx.response 对象包括以下属性和别名方法,详见 Response 章节
上下文对象中的其他 API
以下几种写法都有效: this.throw(403)
this.throw('name required', 400)
this.throw(400, 'name required')
this.throw('something exploded') 实际上, var err = new Error('name required');
err.status = 400;
throw err; 需要注意的是,
Requestctx.request 对象是对 Node 原生请求对象的抽象包装,提供了一些非常有用的方法。 详细的 Request 对象 API 如下: req.header返回请求头 req.method返回请求方法 req.method=设置 req.method ,用于实现输入 req.length返回 req 对象的 req.url返回请求 url req.url=设置请求 url,用于进行 url 重写 req.path返回请求 pathname req.path=设置请求 pathname,如果原有 url 存在查询字符串,则保留这些查询。 req.querystring返回 url 中的查询字符串,去除了头部的 req.querystring=设置查询字符串,不包含 req.search返回 url 中的查询字符串,包含了头部的 req.search=设置查询字符串,包含 req.host返回请求主机名,不包含端口;当 req.type返回 req 对象的 var ct = this.type;
// => "image/png" req.query返回经过解析的查询字符串,类似 Express 中的 req.query,当不存在查询字符串时,返回空对象。 当 url 包含查询字符串 {
color: 'blue',
size: 'small'
} req.query=设置给定的对象为查询对象。范例代码如下: this.query = { next: '/login' }; req.fresh检查客户端请求的缓存是否是最新。当缓存为最新时,可编写业务逻辑直接返回 this.set('ETag', '123');
// 当客户端缓存是最新时
if (this.fresh) {
this.status = 304;
return;
}
// 当客户端缓存已过期时,返回最新的数据
this.body = yield db.find('something'); req.stale与 req.fresh 返回的结果正好相反 req.protocol返回请求协议名,如 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论