1. 程式人生 > >Koa快速入門教程(一)

Koa快速入門教程(一)

Koa 是由 Express 原班人馬打造的,致力於成為一個更小、更富有表現力、更健壯的 Web 框架,採用了asyncawait的方式執行非同步操作。

Koa有v1.0與v2.0兩個版本,隨著node對asyncawait的支援,Koa2的正式釋出,本文Koa均指Koa2

如果你還不熟悉async函式可查閱阮大的ECMAScript 6 入門

這是一篇從零開始的簡易教程,話不多說,先來快速開始:hello world!

一、快速開始

1.1 開發環境

Koa 依賴 node v7.6.0 或 ES2015及更高版本和 async 方法支援,你可以使用自己喜歡的版本管理器快速安裝支援的 node 版本

$ node -v
v8.9.1

如果你的版本號小於v7.6.0,請自行升級。如使用nvm

在確認好環境後,我們就可以新建一個專案,在裡面自由操練了

$ mkdir KoaTutorial && cd KoaTutorial

$ npm i koa --save

1.2 必修的 hello world 應用:

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服務,

來來看看這個hello world程式,其中前兩行和後一行是架設一個 HTTP 服務。中間的則是對使用者訪問的處理。ctx則是Koa所提供的Context物件(上下文),ctx.body=則是ctx.response.body=的alias(別名),這是響應體設定的API。

1.3 Context 物件

Koa Context 將 node 的 request 和 response 物件封裝到單個物件中,為編寫 Web 應用程式和 API 提供了許多有用的方法。上例的ctx.body = ''

即是傳送給使用者內容,它是ctx.response.body的簡寫*(更多請查閱官網)*。ctx.response代表 HTTP Response。ctx.request代表 HTTP Request。

二、路由(URL處理)

2.1 手動實現簡易路由

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

2.2 使用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洋蔥模型

koa2洋蔥模型 我們來執行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/,你將看到返回了頁面:

koa 模板引擎關於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 的內容,訪問http://localhost:3000/koa2.png我們將看見返回下圖

koa2

六、請求資料的獲取

前文我們主要都在處理資料的響應,這兒我們來了解下Koa獲取請求資料,主要為GETPOST方式。

6.1 GET請求引數的獲取

在koa中,獲取GET請求資料來源頭是koa中request物件中的query方法或querystring方法,query返回是格式化好的引數物件,querystring返回的是請求字串。

  • 請求物件ctx.query*(或ctx.request.query)*,返回如 { a:1, b:2 }
  • 請求字串 ctx.querystring*(或ctx.request.querystring)*,返回如 a=1&b=2
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

6.2 POST請求資料獲取

對於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: "[email protected]" }

關於更多的Koa知識快開啟搜尋引擎搜尋*([常用的搜尋引擎技巧])*繼續學習吧,後續將繼續資料庫的操作以及實現一個簡單的小案例。