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知識快打開搜索引擎搜索*([經常使用的搜索引擎技巧])*繼續學習吧,後續將繼續數據庫的操做以及實現一個簡單的小案例。