Koa 是由 Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的 Web 框架,采用了
async
和await
的方式执行异步操做。css
Koa有v1.0与v2.0两个版本,随着node对async
和await
的支持,Koa2的正式发布,本文Koa均指Koa2html
若是你还不熟悉async
函数可查阅阮大的ECMAScript 6 入门node
这是一篇从零开始的简易教程,话很少说,先来快速开始:hello world!git
Koa 依赖 node v7.6.0 或 ES2015及更高版本和 async 方法支持,你可使用本身喜欢的版本管理器快速安装支持的 node 版本es6
$ node -v
v8.9.1
若是你的版本号小于v7.6.0,请自行升级。如使用nvmgithub
在确认好环境后,咱们就能够新建一个项目,在里面自由操练了web
$ mkdir KoaTutorial && cd KoaTutorial $ npm i koa --save
const Koa = require('koa'); const app = new Koa(); app.use(async ctx => { ctx.body = 'Hello World'; }); app.listen(3000);
打开浏览器,访问 http://localhost:3000/,你会看到那可爱的Hello World
。就是这么简单的几行代码,咱们就起了一个HTTP服务,shell
来来看看这个hello world程序,其中前两行和后一行是架设一个 HTTP 服务。中间的则是对用户访问的处理。ctx
则是Koa所提供的Context
对象(上下文),ctx.body=
则是ctx.response.body=
的alias(别名),这是响应体设置的API。数据库
Koa Context 将 node 的 request
和 response
对象封装到单个对象中,为编写 Web 应用程序和 API 提供了许多有用的方法。上例的ctx.body = ''
便是发送给用户内容,它是ctx.response.body
的简写*(更多请查阅官网)*。ctx.response
表明 HTTP Response。ctx.request
表明 HTTP Request。express
koa是个极简的web框架,简单到连路由模块都没有配备,咱们先来能够根据ctx.request.url
或者ctx.request.path
获取用户请求的路径,来实现简单的路由。
const Koa = require('koa'); const app = new Koa(); app.use(async ctx => { let _html = '404 NotFound' switch (ctx.url) { case '/': _html = '<h1>Index</h1>'; break; case '/adout': _html = '<h1>About</h1>'; break; case '/hello': _html = '<h1>world</h1>'; break; default: break; } ctx.body = _html; }); app.listen(3000);
运行这段代码,访问http://localhost:3000/hello将看见world,访问http://localhost:3000/about将看见返回about,访问http://localhost:3000将看见Index。是否是颇有成就感…可是这也太麻烦了吧。若是依靠`ctx.request.url`去手动处理路由,将会写不少代码,这时候就须要对应的路由中间件来对路由进行控制: koa-router
下载并引入koa-router
npm i koa-router --save
const Koa = require('koa'); const Router = require('koa-router'); const app = new Koa(); const router = new Router(); router.get('/', async (ctx) => { let html = ` <ul> <li><a href="/hello">helloworld</a></li> <li><a href="/about">about</a></li> </ul> ` ctx.body = html }).get('/hello', async (ctx) => { ctx.body = 'helloworld' }).get('/about', async (ctx) => { ctx.body = 'about' }) app.use(router.routes(), router.allowedMethods()) app.listen(3000);
运行这个 demo,咱们将看到与上栗同样的效果。在这儿咱们使用到了第三方中间件。
Koa 的最大特点,也是最重要的一个设计,就是中间件(middleware)Koa 应用程序是一个包含一组中间件函数的对象,它是按照相似堆栈的方式组织和执行的。Koa中使用app.use()
用来加载中间件,基本上Koa 全部的功能都是经过中间件实现的。每一个中间件默认接受两个参数,第一个参数是 Context 对象,第二个参数是next
函数。只要调用next
函数,就能够把执行权转交给下一个中间件。
下图为经典的Koa洋葱模型
const Koa = require('koa'); const app = new Koa(); // 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`); }); // logger app.use(async (ctx, next) => { const start = Date.now(); await next(); const ms = Date.now() - start; console.log(`${ctx.method} ${ctx.url} - ${ms}`); }); // response app.use(async ctx => { ctx.body = 'Hello World'; }); app.listen(3000);
上面的执行顺序就是:请求 ==> x-response-time中间件 ==> logger中间件 ==> 响应中间件 ==> logger中间件 ==> response-time中间件 ==> 响应。 经过这个顺序咱们能够发现这是个栈结构以"先进后出"(first-in-last-out)的顺序执行。Koa已经有了不少好用的中间件*(https://github.com/koajs/koa/wiki#middleware)你须要的经常使用功能基本上都有人实现了*
在实际开发中,返回给用户的网页每每都写成模板文件。 Koa 先读取模板文件,而后将这个模板返回给用户,这事咱们就须要使用模板引擎了,关于Koa的模版引擎,咱们只须要安装koa模板使用中间件koa-views 而后在下载你喜欢的模板引擎*(支持列表)*即可以愉快的使用了。如安装使用ejs
# 安装koa模板使用中间件 $ npm i --save koa-views # 安装ejs模板引擎 $ npm i --save ejs
const Koa = require('koa') const views = require('koa-views') const path = require('path') const app = new Koa() // 加载模板引擎 app.use(views(path.join(__dirname, './view'), { extension: 'ejs' })) app.use(async (ctx) => { let title = 'Koa2' await ctx.render('index', { title, }) }) app.listen(3000)
./view/index.ejs
模板
<!DOCTYPE html>
<html>
<head> <title><%= title %></title> </head> <body> <h1><%= title %></h1> <p>EJS Welcome to <%= title %></p> </body> </html>
打开http://localhost:3000/,你将看到返回了页面:
关于ejs语法请访问ejs官网学习:https://github.com/mde/ejs
网站通常都提供静态资源(图片、字体、样式表、脚本……),咱们能够本身实现一个静态资源服务器,但这不必,koa-static模块封装了这部分功能。
$ npm i --save koa-static
const Koa = require('koa') const path = require('path') const static = require('koa-static') const app = new Koa() // 静态资源目录对于相对入口文件index.js的路径 const staticPath = './static' app.use(static( path.join(__dirname, staticPath) )) app.use(async (ctx) => { ctx.body = 'hello world' }) app.listen(3000)
咱们访问http://localhost:3000/css/app.css 将返回app.css
的内容
前文咱们主要都在处理数据的响应,这儿咱们来了解下Koa获取请求数据,主要为GET
和POST
方式。
在koa中,获取GET请求数据源头是koa中request对象中的query方法或querystring方法,query返回是格式化好的参数对象,querystring返回的是请求字符串。
const Koa = require('koa') const app = new Koa() app.use( async ( ctx ) => { const url = ctx.url const query = ctx.query const querystring = ctx.querystring ctx.body = { url, query, querystring } }) app.listen(3000)
运行程序并访问http://localhost:3000/?page=2&limit=10,咱们将获得以下结果
{"url":"/?page=2&limit=10","query":{"page":"2","limit":"10"},"querystring":"page=2&limit=10"}
对了,在这儿推荐个插件:JSONView,用了它你将获得格式化json数据,以下:
{
url: "/?page=2&limit=10", query: { page: "2", limit: "10" }, querystring: "page=2&limit=10" }
更多Koa Request API 请查看http://koajs.com/#request
对于POST请求的处理,koa2没有封装获取参数的方法,须要经过本身解析上下文context中的原生node.js请求对象req,将POST表单数据解析成querystring(例如:a=1&b=2&c=3
),再将querystring 解析成JSON格式(例如:{"a":"1", "b":"2", "c":"3"}
),咱们来直接使用koa-bodyparser 模块从 POST 请求的数据体里面提取键值对。
const Koa = require('koa') const app = new Koa() const bodyParser = require('koa-bodyparser') // 使用koa-bodyparser中间件 app.use(bodyParser()) app.use(async (ctx) => { if (ctx.url === '/' && ctx.method === 'GET') { // 当GET请求时候返回表单页面 let html = ` <h1>koa-bodyparser</h1> <form method="POST" action="/"> Name:<input name="name" /><br/> Age:<input name="age" /><br/> Email: <input name="email" /><br/> <button type="submit">submit</button> </form> ` ctx.body = html } else if (ctx.url === '/' && ctx.method === 'POST') { // 当POST请求的时候,中间件koa-bodyparser解析POST表单里的数据,并显示出来 ctx.body = ctx.request.body } else { // 404 ctx.body = '<h1>404 Not Found</h1>' } }) app.listen(3000)
运行程序,填写并提交表单,请求结果为:
{
name: "ogilhinn", age: "120", email: "ogilhinn@gmail.com" }
关于更多的Koa知识快打开搜索引擎搜索*([经常使用的搜索引擎技巧])*继续学习吧,后续将继续数据库的操做以及实现一个简单的小案例。