Koa框架教程Node主要用在开发Web应用。这决定了使用Node,往往离不开Web应用框架。Koa就是一种简单好用的Web框架。它的特点是优雅、简洁、表达力强、自由度高。本身代码只有1000多行,所有功能都通过插件实现,很符合Unix哲学。本文从零开始,循序渐进,教会你如何使用Koa写出自己的Web应用。每一步都有简洁易懂的示例,希望让大家一看就懂。零、准备首先,检查Node版本。$node-vv8.0.0Koa必须使用7.6以上的版本。如果你的版本低于这个要求,就要先升级Node。然后,克隆本文的配套示例库()。(如果不方便使用Git,也可以下载zip文件解压。)$gitclone接着,进入示例库,安装依赖。$cdkoa-demos$npminstall所有示例源码,都在demos()目录下面。一、基本用法1.1架设HTTP服务只要三行代码(),就可以用Koa架设一个HTTP服务。//demos/01.jsconstKoa=require('koa');constapp=newKoa();app.listen(3000);运行这个脚本。$nodedemos/01.js打开浏览器,访问。你会看到页面显示'NotFound',表示没有发现任何内容。这是因为我们并没有告诉Koa应该显示什么内容。1.2Context对象Koa提供一个Context对象,表示一次对话的上下文(包括HTTP请求和HTTP回复)。通过加工这个对象,就可以控制返回给用户的内容。Context.response.body属性就是发送给用户的内容。请看下面的例子(完整的代码看这里)。//demos/02.jsconstKoa=require('koa');constapp=newKoa();constmain=ctx={ctx.response.body='HelloWorld';};app.use(main);app.listen(3000);上面代码中,main函数用来设置ctx.response.body。然后,使用app.use方法加载main函数。你可能已经猜到了,ctx.response代表HTTPResponse。同样地,ctx.request代表HTTPRequest。运行这个demo。$nodedemos/02.js访问,现在就可以看到'HelloWorld'了。1.3HTTPResponse的类型Koa默认的返回类型是text/plain,如果想返回其他类型的内容,可以先用ctx.request.accepts判断一下,客户端希望接受什么数据(根据HTTPRequest的Accept字段),然后使用ctx.response.type指定返回类型。请看下面的例子(完整代码看这里)。//demos/03.jsconstmain=ctx={if(ctx.request.accepts('xml')){ctx.response.type='xml';ctx.response.body='HelloWorld';}elseif(ctx.request.accepts('json')){ctx.response.type='json';ctx.response.body={data:'HelloWorld'};}elseif(ctx.request.accepts('html')){ctx.response.type='html';ctx.response.body='HelloWorld';}else{ctx.response.type='text';ctx.response.body='HelloWorld';}};运行这个demo。$nodedemos/03.js访问,现在看到的就是一个XML文档了。1.4网页模板实际开发中,返回给用户的网页往往都写成模板文件。我们可以让Koa先读取模板文件,然后将这个模板返回给用户。请看下面的例子(完整代码看这里:)。//demos/04.jsconstfs=require('fs');constmain=ctx={ctx.response.type='html';ctx.response.body=fs.createReadStream('./demos/template.html');};运行这个Demo。$nodedemos/04.js访问,看到的就是模板文件()的内容了。二、路由2.1原生路由网站一般都有多个页面。通过ctx.request.path可以获取用户请求的路径,由此实现简单的路由。请看下面的例子(完整代码看这里:)。//demos/05.jsconstmain=ctx={if(ctx.request.path!=='/'){ctx.response.type='html';ctx.response.body='IndexPage';}else{ctx.response.body='HelloWorld';}};运行这个demo。$nodedemos/05.js访问,可以看到一个链接,点击后就跳到首页。2.2koa-route模块原生路由用起来不太方便,我们可以使用封装好的koa-route模块。请看下面的例子(完整代码看这里)。//demos/06.jsconstroute=require('koa-route');constabout=ctx={ctx.response.type='html';ctx.response.body='IndexPage';};constmain=ctx={ctx.response.body='HelloWorld';};app.use(route.get('/',main));app.use(route.get('/about',about));上面代码中,根路径/的处理函数是main,/about路径的处理函数是about。运行这个demo。$nodedemos/06.js访问,效果与上一个例子完全相同。2.3静态资源如果网站提供静态资源(图片、字体、样式表、脚本......),为它们一个个写路由就很麻烦,也没必要。koa-static模块封装了这部分的请求。请看下面的例子(完整代码看这里:)。//demos/12.jsconstpath=require('path');constserve=require('koa-static');constmain=serve(path.join(__dirname));app.use(main);运行这个Demo。$nodedemos/12.js访问,在浏览器里就可以看到这个脚本的内容。2.4重定向有些场合,服务器需要重定向(redirect)访问请求。比如,用户登陆以后,将他重定向到登陆前的页面。ctx.response.redirect()方法可以发出一个302跳转,将用户导向另一个路由。请看下面的例子(完整代码看这里:)。//demos/13.jsconstredirect=ctx={ctx.response.redirect('/');ctx.response.body='IndexPage';};app.use(route.get('/redirect',redirect));运行这个demo。$nodedemos/13.js访问,浏览器会将用户导向根路由。三、中间件3.1Logger功能Koa的最大特色,也是最重要的一个设计,就是中间件(middleware)。为了理解中间件,我们先看一下Logger(打印日志)功能的实现。最简单的写法就是在main函数里面增加一行(完整代码看这里:)。//demos/07.jsconstmain=ctx={console.log(`${Date.now()}${ctx.request.method}${ctx.request.url}`);ctx.response.body='HelloWorld';};运行这个Demo。$nodedemos/07.js访问,命令行就会输出日志。1502144902843GET/3.2中间件的概念上一个例子里面的Logger功能,可以拆分成一个独立函数(完整代码看这里:)。//demos/08.jsconstlogger=(ctx,next)={console.log(`${Date.now()}${ctx.request.method}${ctx.request.url}`);next();}app.use(logger);像上面代码中的logger函数就叫做'中间件'(middleware),因为它处在HTTPRequest和HTTPResponse中间,用来实现某种中间功能。app.use()用来加载中间件。基本上,Koa所有的功能都是通过中间件实现的,前面例子里面的main也是中间件。每个中间件默认接受两个参数,第一个参数是Context对象,第二个参数是next函数。只要调用next函数,就可以把执行权转交给下一个中间件。运行这个demo。$nodedemos/08.js访问,命令行窗口会显示与上一个例子相同的日志输出。3.3中间件栈多个中间件会形成一个栈结构(middlestack),以'先进后出'(first-in-last-out)的顺序执行。1.最外层的中间件首先执行。2.调用next函数,把执行权交给下一个中间件。3....4.最内层的中间件最后执行。5.执行结束后,把执行权交回上一层的中间件。6....7.最外层的中间件收回执行权之后,执行next函数后面的代码。请看下面的例子(完整代码看这里: