koa文档参考
koa文档
简介
koa 是由 Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的 Web 框架。使用 koa 编写 web 应用,通过组合不同的 generator,可以免除重复繁琐的回调函数嵌套,并极大地提升错误处理的效率。koa 不在内核方法中绑定任何中间件,它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手。
koa1.x的用generator, koa2.x用async/await, node各个版本对es6的支持程度,可参考 node.green
Koa 应用是一个包含一系列中间件 generator 函数的对象。 这些中间件函数基于 request 请求以一个类似于栈的结构组成并依次执行。 Koa 类似于其他中间件系统(比如 Ruby's Rack 、Connect 等), 然而 Koa 的核心设计思路是为中间件层提供高级语法糖封装,以增强其互用性和健壮性,并使得编写中间件变得相当有趣。
Koa 包含了像 content-negotiation(内容协商)、cache freshness(缓存刷新)、proxy support(代理支持)和 redirection(重定向)等常用任务方法。 与提供庞大的函数支持不同,Koa只包含很小的一部分,因为Koa并不绑定任何中间件。
hello world示例:
//koa 2.x
var Koa = require('koa');
var app = new Koa();
app.use(async (ctx, next) => {
ctx.body = 'Hello World';
});
app.listen(3000);
console.log('server listening at 3000');
中间件
Koa 的中间件通过一种更加传统(您也许会很熟悉)的方式进行级联,摒弃了以往 node 频繁的回调函数造成的复杂代码逻辑。 我们通过 generators 来实现“真正”的中间件。 Connect 简单地将控制权交给一系列函数来处理,直到函数返回。 与之不同,当执行到 yield next 语句时,Koa 暂停了该中间件,继续执行下一个符合请求的中间件('downstrem'),然后控制权再逐级返回给上层中间件('upstream')。
koa1.x 和 koa2.x的中间件机制是一样的,区别在于koa1.x用generator书写,koa2.x用async/await; async/await本质上是generator的语法糖,generator的本质是一个迭代器,需要runner去触发下一阶段的执行.
中间件的栈执行顺序(后进先出),类似html标签层层嵌套,从顶层到底层,在从底层开始闭合(其实dom的事件机制也类似)
示例:
//> koa 2.x
var Koa = require('koa');
var app = new Koa();
// mw: x-response-time
app.use(async (ctx,next) => {
let start = new Date;
await next();
let ms = new Date - start;
ctx.set('X-Response-time', ms + 'ms');
});
// mw: logger
app.use(async (ctx, next) => {
let start = new Date;
await next();
let ms = new Date - start;
console.log('%s %s - %d', ctx.method, ctx.url, ms);
});
// mw: response
app.use(async (ctx, next) => {
ctx.body = 'Hello World'; // 设置响应内容后,还可以 ctx.se(..) 设置响应头
});
app.listen(3012);
console.log('server listening at 3012');
//> koa 1.x
var koa = require('koa');
var app = koa();
// x-response-time
app.use(function* (next) {
let start = new Date;
yield next;
var ms = new Date - start;
this.set('X-Response-Time', ms + 'ms');
});
// logger
app.use(function* (next) {
let start = new Date;
yield next;
let ms = new Date - start;
console.log('%s %s - %d', this.method, this.url, ms);
});
// response
app.use(function* (next) {
this.body = 'Hello World~~';
});
app.listen(3012);
console.log('server listen at 3012');
配置
app实例的配置属性:
- app.name 应用名称
- app.env 环境变量(默认为 process.env.NODE_ENV || 'development')
- app.proxy 若为true, 则解析header(请求头),并支持 X-Forwarded-Host
- app.subdomainOffset 默认2,表示 app.subdomains, 所忽略的segment个数
app.listen(port)
app.listen(3000) 创建并返回一个http服务器.
// app.listen() 同下
var http = require('http');
http.createServer(app.callback()).listen(3000);
http.createServer(app.callback()).listen(3001); // 同一个应用运行在多个端口上
app.callback()
app.callback() 返回request callback函数,可用于 http.createServer(app.callback())
app.use(middleware)
app.use(mw) 为应用添加中间件
app.keys
app.keys = ['i am secrect', 'hello'] 设置 signed cookie 的密钥
ctx.cookies.set('name', 'sandy', {signed: true})设置加密的cookie
错误处理
默认所有的错误信息会输出到 stderr, 可以监听error事件,实现自动的错误处理.
app.on('error', function(err, context) {
// 若处理请求阶段出错,不能响应时,会有context参数传入回调
console.error('server error:', err);
});
上下文对象
Koa Context 将 node 的 request 和 response 对象封装在一个单独的对象里面,其为编写 web 应用和 API 提供了很多有用的方法。
context 在每个 request 请求中被创建.
koa 1.x 的上下文对象为中间件的 this, koa 2.x 的上下文对象,为中间件的参数1
// koa 1.x
app.use(function* (next) {
this.body = 'good'; // this is context obj
});
// koa 2.x
app.use(async (ctx, next) => {
ctx.body = 'good2'; // ctx is context obj
});
为了便于访问和调用,许多 context 的属性和方法,代理了 ctx.request 和 ctx.response 所对应的等价方法, 比如说 ctx.type 和 ctx.length 代理了 response 对象中对应的方法,ctx.path 和 ctx.method 代理了 request 对象中对应的方法。
ctx.reqnodejs的request对象ctx.resnodejs的response对象ctx.requestkoa的request对象, 包装后的nodejs的request对象ctx.responsekoa的response对象ctx.app应用实例的引用ctx.cookies.get(name, [options])获取coolie, koa使用了Express的cookies模块ctx.cookies.set(name, value, [options])设置cookie,options = {
signed: true,
expires: time,
path: '/',
domain: 'a.com',
secure: false,
httpOnly: true
}
ctx.throw(msg, [status])抛出异常// 适配 msg status两个参数的顺序,缺少的则用默认值
ctx.throw(403);
ctx.throw('some error');
ctx.throw('name required', 400);
ctx.throw(400, 'name required');
ctx.responsectx.response = false 时,可以通过ctx.res直接使用原生的response对象, 但不推荐这样做ctx.request对象释放到ctx上的方法和属性// url and method
ctx.urlctx.originalUrlread onlyctx.protocolread onlyctx.hostread onlyctx.hostnameread onlyctx.pathctx.queryctx.querystringctx.method
// header
ctx.headerread onlyctx.get(headerName)ctx.is()判断 content-typectx.accepts()accepts content-typectx.acceptsEncodings()ctx.acceptsLanguage()ctx.accepetsCharsets()
// others
ctx.ipread onlyctx.ipsread onlyctx.secureread onlyctx.subdomainsread onlyctx.freshread onlyctx.staleread onlyctx.socketread only
ctx.response对象释放到ctx上的方法和属性// 响应体
ctx.bodyctx.attachment()
// 响应头
ctx.set(name,val)设置响应头ctx.remove()删除响应头ctx.status状态码ctx.lengthcontent-lengthctx.typecontent-typectx.lastModified缓存相关响应头ctx.etag
// 其他
ctx.headerSent是否已发送响应头ctx.redirect()重定向
ctx.request对象的完整属性方法// url and method
ctx.request.methodctx.request.urlctx.request.originalUrlctx.request.protocolctx.request.hosthostname:portctx.request.hostnamectx.request.pathctx.request.queryeg: {color: 'blue', size: 'small'} 不支持嵌套对象ctx.request.querystringeg: foo=bar&go=finectx.request.searcheg: ?foo=bar&go=fine
// header
ctx.request.get()ctx.request.headerctx.request.typecontent-type eg: image/pngctx.request.lengthcotent-lengthctx.request.charseteg: utf-8ctx.request.is()eg: ctx.is('html'), ctx.is('text/html'), ctx.is('html', 'application/*'), ctx.is('application/json')
// others
ctx.request.fresh若用(*If-None-Match/ETag, If-Modified-Since/Last-Modified)进行缓存协商,则该属性表示协商结果ctx.request.stale与 ctx.request.fresh 相反ctx.request.securectx.request.ipctx.request.ipsctx.request.subdomainsctx.request.socketctx.request.idempotent请求是否幂等
// 内容协商
ctx.request.accepts(types)eg: ctx.accepts('html') ctx.accepets('json', 'text')ctx.request.acceptsEncoding(encodings)eg: ctx.acceptsEncodings('gzip', 'deflate','identity')ctx.request.acceptsLanguages(langs)eg: this.acceptsLanguages('es', 'en')ctx.request.acceptsCharsets(charsets)eg: ctx.acceptsCharsets('utf-8')
ctx.response对象的完整属性// 响应体
ctx.response.bodyeg: ctx.body = String/Buffer/Stream/Objectctx.response.attachment([filename])
// 响应头
ctx.response.get(field)eg: ctx.response.get('ETag') 响应头(field)不区分大小写ctx.response.set(field, value)eg: ctx.set('cache-control', 'no-cache')ctx.response.remove(field)ctx.response.append(field, val)为指定头部追加值ctx.response.headerctx.response.statuseg: ctx.response.status = 301;ctx.response.statusStringctx.response.lengthcontent-lengthctx.response.typecontent-type eg: image/png , .png , pngctx.response.lastModifiedeg: ctx.lastModified = new Date()ctx.response.etageg: ctx.response.etag = crypto.createHash('md5').update(ctx.body).digest('hex');
// 其他
ctx.response.headerSentctx.response.vary(field)等价于 ctx.response.append('Vary', field)ctx.response.socketctx.response.redirect(url, [alt])ctx.redirect('back');
ctx.redirect('back', '/index.html')
ctx.redirect('/login');
ctx.redirect('http://google.com');
koa文档参考的更多相关文章
- MiniGUI文档参考手册 基于v1.6.10文本
MiniGUI各种功能都分布在预先定义宏对每个文档标题.特别不方便查找,这是不利于初学者学习. 有一天,我发现doxygen,因此,使用该工具可以生成一个minigui参考文献 .基于v1.6.10文 ...
- 通过XmlDocument读写Xml文档参考地址
/// <summary> /// 获取一个报表的参数 http://blog.csdn.net/hdhai9451/article/details/12170069 /// </s ...
- koa文档笔记
请求 get ctx.request.query // 查询对象 ctx.request.querystring // 查询字符串 ctx.query // 查询对象 ctx.querystring ...
- rem布局js设置,设置网页文档参考字体闭包函数
(function (doc, win) { var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? ...
- FORM实现中打开图片,链接,文档(参考自itpub上一篇帖子,整理而来)
FORM实现中打开图片,链接,文档 参考自itpub上一篇帖子,整理而来 1.添加PL程序库D2kwutil.pll 2.主要实现程序 /*过程参数说明: v_application --打开文件的应 ...
- Nodejs v4.x.0API文档学习(2)Assert断言测试模块
文档参考地址:https://nodejs.org/dist/latest-v4.x/docs/api/ Assert(断言) assert模块提供了一组简单的断言测试方法,可以拥有测试不变量.该模块 ...
- Nodejs v4.x.0API文档学习(1)简介
文档参考地址:https://nodejs.org/dist/latest-v4.x/docs/api/ 简介 下面是用nodejs编写的一个web服务的例子,返回"Hello World& ...
- 制作Net程序的帮助文档--总结
一.工具的准备 目前,一般采用Sandcastle Help File Builder工具来制作.Net程序帮助文档,该工具主要是利用Xml文档里的信息以及DLL文件来生成完整的帮助文档.在Visua ...
- Java 初学者帮助文档以及基础教程
一下午的时间,大致看了一下Java的文档,进一步熟悉了Java的大体框架和结构,整理了一下有用的资源. 帮助文档: JSE 8 API 英文版 在线HTML格式:http://docs.oracle. ...
随机推荐
- JS垃圾收集机制
JS 具有自动垃圾回收机制,不需要像C++/C等语言去手动跟踪内存使用情况. 垃圾收集方式: 1.标记清除: 垃圾收集器在运行时给存储在内存中的所有变量都加上标记,然后,它会去掉环境中的变量,以及被环 ...
- Flask路由
@app.route() methods:当前url地址,允许访问的请求方式 @app.route("/info", methods=["GET", " ...
- js计算本地时间
获取时间戳: 方法一 var dateTime = new Date();//获取本地时间 var nowTime = dateTime.getTime();//获取本地毫秒,即当前时间 var en ...
- 一步步完成Maven+SpringMVC+SpringFox+Swagger整合示例
本文给出一个整合Maven+SpringMVC+SpringFOX+Swagger的示例,并且一步步给出完成步骤. 本人在做实例时发现 http://blog.csdn.net/zth1002/art ...
- poj3268 Silver Cow Party(两次dijkstra)
https://vjudge.net/problem/POJ-3268 一开始floyd超时了.. 对正图定点求最短,对逆图定点求最短,得到任意点到定点的往返最短路. #include<iost ...
- 轻量级的Web框架——Nancy
最近想找一个简单的.Net下的轻量级Web框架,作为用户的本地的一个WebServer,实现同浏览器程序的一些简单交互,并调用本地服务,实现类似浏览器插件的功能.它有如下几点要求: 简单,能快速账务, ...
- Unity设置播放模式下始终先执行指定的场景
通过我们使用Unity开发游戏,是在PC/Mac上.而一个游戏通常也会有很多的场景,比如A.B.C.D三个场景,正常流程下的执行顺序是 A –> B –> C –> D.在具体一点, ...
- Java的内存管理机制之内存区域划分
各位,好久不见.先做个预告,由于最近主要在做Java服务端开发,最近一段时间会更新Java服务端开发相关的一些知识,包括但不限于一些读书笔记.框架的学习笔记.和最近一段时间的思考和沉淀.先从Java虚 ...
- Lombok 使用攻略
1. Lombok 简介 Lombok 可以通过简单的注解来帮助我们简化消除一些必须有但显得很臃肿的Java代码,通过使用对应的注解,可以在编译源码的时候生成对应的方法. Lombok 既是一个 ID ...
- WebApp开发技术搭配
一:Ionic + angular + cordova + zipalign UI框架:lonic+angular 开发与编译打包框架:Cordova 优化工具:zipalign 二:MUI+HBui ...