Koa2框架解读
1.中间件一个koa应用就是一个对象,包含了一个middleware数组,这个数组由一组Generator函数组成,这些函数负责对HTTP请求进行各种加工,比如生成缓存、指定代理、请求重定向等等。(app.use方法用于向middleware数组添加Generator函数,listen方法指定监听端口,并开启当前应用。koa2的中间件就是对HTTP请求进行处理的函数,但是必须使yigeGengerator函数,而且,koa的中间件是一个级联式的结构,也就是说,属于层层调用,第一个中间件调用第二个,第二个调用第三个,以此类推,上游的中间件必须等到下游的中间件返回结果才会继续执行,这点很递归。yield next相当于把程序的执行权交给下一个中间件,需要注意的是,只要有一个中间件缺少yield next语句,后面的中间件都不会执行。由于koa要求中间件唯一的参数就是next,导致如果要传入其他参数,必须另外写一个返回Gengerator函数的函数。
function logger(format){ return function *(next){ var str=format .replace(':method',this.method) .replace(':url',this.url); console.log(str); yield next; } } app.use(logger(':method :url'));多个中间件的合并:由于中间件的参数统一为next(意为下一个中间件),因此可以使用.call(this,next),将多个中间件进行合并。这里就是中间件all内部,依次调用random、backwards,pi,后一个中间件就是前一个中间件的参数
function *random(next){ if('/random'==this.path){ this.body=Math.floor(Math.random()*10); }else{ yield next; } }; function *backwards(next){ if('/backwards'==this.path){ this.body='sdrawsa' }else{ yield next; } } function *pi(next){ if('/pi'==this.path){ this.body=String(Math.PI); }else{ yield next; } } function *all(next){ yield random.call(this.backwards.call(this,pi.call(this,next))) } app.use(all);2. 关于koa的路由,可以通过this.path属性,判定用户请求的路径,从而起到路由的作用。Koa-router实例提供一系列动词方法,即一种HTTP动词对应一种方法,典型的动词方法有以下五种:router.get(),router.post(),router.put(),router.del(),router.patch(),这些动词方法可以接受两个参数,一个数路径模型,一个是对应的控制器方法(中间件),定义用户请求该路径时服务器行为。(注意:路径匹配的时候,不会把查询字符串考虑在内,比如,/index?param=xyz匹配路径/index)
router.get('/',function *(next){ this.body='Hello World!'; });有些路径模式比较复杂,Koa-router允许路径模型起别名,起名时,别名要添加为动词方法的第一个参数,这时动词方法变成接受三个参数。
router.get('user','/users/:id',function *(next){ //... })router.url可以根据给定的路径生成url,同时也可以为路径统一添加前缀。
var router = new Router({ prefix: '/users' }); router.get('/', ...); // 等同于"/users" router.get('/:id', ...); // 等同于"/users/:id"路径的参数通过this.params属性获取,该属性返回一个对象,所有的路径参数都是该对象的成员。
router.get('/:category/:title', function *(next) { console.log(this.params); // => { category: 'programming', title: 'how-to-node' } });redirect方***将某个路径的请求,重定向到另一个路径,并返回301状态码。redirect方法的第一个参数是请求来源,第二个参数是目的地,两者都可以用路径模式的别名代替。
router.redirect('/login', 'sign-in'); // 等同于 router.all('/login', function *() { this.redirect('/sign-in'); this.status = 301; });3.context对象:中间件当中的this表示上下文对象context,代表一次HTTP请求和回应,即一次访问/回应的所有信息,都可以从上下文对象获得。context对象封装了request和response对象,并提供了一些辅助方法,每次HTTP请求,就会创建一个新的context对象。context对象有很多的方法,其实是定义在ctx.request对象或者ctx.response对象上面,比如,ctx.type和ctx.length对应于ctx.response.type和ctx.response.length,ctx.path和ctx.method对应于ctx.request.path和ctx.request.method。
4.错误处理机制,Koa提供内置的错误处理机制,任何中间件抛出的错误都会被捕捉到,引发向客户端返回一个500错误,而不会导致进程停止。
app.use(function *() { try { yield saveResults(); } catch (err) { this.throw(400, '数据无效'); } });对于未捕获错误,可以设置error事件的监听函数。
app.on('error', function(err){ log.error('server error', err); });5.cookie和sessIon,cookie的读取和设置,get和set方法都尅接受第三个参数,表示配置参数,其中的signed参数,用于指定cookie是否加密,如果指定加密的话,必须用app.keys指定加密短语。
this.cookies.get('view'); this.cookies.set('view', n); app.keys = ['secret1', 'secret2']; this.cookies.set('name', '张三', { signed: true });6.request对象和response对象,最后提一嘴koa-compress模块可以实现数据压缩。