前言
這是一個關于KOA的內部分享交流講稿,簡述了KOA的一些特點及逐步搭建一個簡單的SSR架子的過程。
內容收集自度娘,希望閱讀下文的兄dei有所收獲。
前置知識
- node
- ES6
講稿
part0 Koa簡介及分享內容介紹

Koa -- 基于 Node.js 平臺的下一代 web 開發(fā)框架,它是由 Express 原班人馬打造的,特點:優(yōu)雅、簡潔、靈活、體積小。
Why Koa

為什么我們選擇用Koa呢?這需要從兩方面談起
-
第一點,是我們需要SSR(服務器端渲染)所以需要node的web應用框架
現(xiàn)在我們的wap端用的是vue技術棧做的單頁面應用,它的優(yōu)點是:
1、頁面跳轉不需要刷新,用戶體驗流暢。
2、前后端只需要用API交互,實現(xiàn)前后端分離。
3、實現(xiàn)前端頁面路由功能,頁面的拼接、顯示邏輯均在客戶端完成,減輕服務器壓力。
但是,單頁面應用有個不能回避的問題,就是SEO(Search Engine Optimization):搜索引擎優(yōu)化不友好。
PC端需要通過搜索引擎做入口,所以需用到SSR的項目架構。
-
第二點,是在web應用框架中,Koa比較符合我們項目的體量, 市面上主流框架有三種,hapi express koa ,還有一些是經過一些封裝和定制的框架,例如:eggjs等。
eggjs的功能很強大,有很多功能,多到有些根本用不著,從而導致這個框架太重。
koa是express的原班人馬打造,屬于對express的升級。也是現(xiàn)在社區(qū)比較熱門的web框架,因此我們選擇了Koa。
What we talk about

這次的分享,會從以下幾點開展
1.介紹基本用法。 首先,我們跑起一個最基本的Koa應用,實現(xiàn)在瀏覽器顯示hello world。
2.介紹上下文對象。 Koa Context 將 node 的 request 和 response 對象封裝到單個對象中,為編寫 Web 應用程序和 API 提供了許多有用的方法。
3.介紹Koa的中間件(middleware) 這是 Koa 的最大特色,也是最重要的一個設計,Koa 應用程序是一個包含一組中間件函數(shù)的對象,它是按照類似堆棧的方式組織和執(zhí)行的。
4.介紹Koa獲取請求后的一些處理。 包括路由、解析數(shù)據(jù)、鑒權
5.介紹Koa對靜態(tài)資源的處理
6.介紹Koa如何搭配模板引擎
7.最后,因為node是跑在服務器上,所以介紹一下性能優(yōu)化與安全相關的內容
part1 基本用法(手把手教你寫hello World)

- 第一步,我們首先檢查node的版本。 Koa是node的一個web應用框架,首先要檢查是否已經安裝了node,因為Koa需要支持async方法,所以node版本要大于7.6
- 第二步,安裝Koa。 先npm init 初始化包管理配置文件,再npm install koa 下載koa的資源包,
- 第三步,編寫入口文件腳本。 先require引入koa,new一個實例,listen3000端口。
- 最后啟動服務,打開網(wǎng)頁。 就可以看頁面請求localhost:3000,Koa接受到請求后,返回Hello World!的內容。
part2 上下文(context)

介紹
- 我們接收到客戶端的請求,需要根據(jù)請求的內容做相應的操作,增刪改查數(shù)據(jù)、返回頁面等等。
- Koa Context 將 node 的 request 和 response 對象封裝到單個對象中,為編寫 Web 應用程序和 API 提供了許多有用的方法。
比如:
- 獲取、設置cookies
- 獲取request headers,設置respond headers
- 獲取請求源、請求協(xié)議
- 設置響應狀態(tài)、設置緩存字段等
這里Koa推薦ctx.state這個命名空間,可用于通過中間件傳遞信息和前端視圖。
代碼展示

每個向Koa發(fā)起的請求都將創(chuàng)建一個 Context 上下文對象,并在中間件中作為接收器引用,一般用 ctx 標識符,如以下代碼片段所示:
這是在控制臺打印出來的ctx信息,有各種請求的相關信息
part3 中間件(Middleware)
介紹

- Koa 的最大特色,也是最重要的一個設計,就是中間件(middleware),Koa 應用程序就是一個包含一組中間件函數(shù)的對象;
- 每個中間件默認接受兩個參數(shù),第一個參數(shù)是 Context 對象,第二個參數(shù)是next函數(shù);
- 中間件是按照類似堆棧的方式組織和執(zhí)行的。我們看這個中間件執(zhí)行順序GIF。程序由上到下執(zhí)行,在中間件中遇到next(),就將執(zhí)行權移交給下一個中間件。當最后一個中間件執(zhí)行完成,這里一般是向頁面返回數(shù)據(jù)后。中間件就往回繼續(xù)執(zhí)行,直到返回第一個中間件。
- 就像這個洋蔥圖一樣,請求從左至右。所有的請求經過一個中間件的時候都會執(zhí)行兩次,對比 Express 形式的中間件,Koa 的模型可以非常方便的實現(xiàn)后置處理邏輯;
對比 Koa 和 Express 的 Compress 中間件就可以明顯的感受到 Koa 中間件模型的優(yōu)勢。
koa-compress for Koa. https://github.com/koajs/compress/blob/master/index.js
compression for Express. https://github.com/expressjs/compression/blob/master/index.js
在demo中,我們利用這個特性可以寫個統(tǒng)計請求處理時間的中間件
這里需要注意的是,node里面是充滿異步的世界,因此,在中間件里,我們使用async 函數(shù)(generator函數(shù)的語法糖)并 await next(),實現(xiàn)等待異步
中間件實現(xiàn)簡易路由

- koa是個極簡的web框架,簡單到連路由模塊都沒有配備,我們先來可以根據(jù)ctx.request.url或者ctx.request.path獲取用戶請求的路徑,來實現(xiàn)簡單的路由。
- 但當項目龐大起來時,手寫這種路由時就變得繁瑣,我們一般用對應的路由中間件koa-router來對路由進行控制。
part4 請求處理(request)
- 這里主要說一下KOA如何處理路由、數(shù)據(jù)解析、鑒權。
Koa-router

這里首先說一下路由
- 剛剛說中間件的時候,我們手動實現(xiàn)了一個簡單的路由功能,但實際項目中,我們會借助koa-router這個中間件
- 一般在項目中,我們會這樣組織代碼
- app.js是項目的入口文件,在app.js中import路由文件,并注冊路由信息;
- 路由文件寫在routes文件夾下,用router實例下的get、post等方法,匹配請求;
- 根據(jù)匹配到的路徑,調用到controller.js的不同方法,渲染頁面或返回數(shù)據(jù);
- 如果有復雜的異步業(yè)務操作,我們再抽離到service文件中。
koa-bodyparser

- koa.js并沒有內置Request Body的解析器,當我們需要解析請求體時官方提供的koa-bodyparser是個很不錯的選擇,它支持form、json、text等格式的請求體。
- bodyparser比較簡單,直接引入進來,use一下就可以??蛇x的配置有:允許的類型,編碼方式,請求體大小等。一般配置一下enableTypes,其他默認就可以。
koa-session
介紹

HTTP是無狀態(tài)協(xié)議,為了保持用戶狀態(tài),我們一般使用Session會話,koa-session提供了這樣的功能,既支持將會話信息存儲在本地Cookie,也支持存儲在如Redis, MongoDB這樣的外部存儲設備。
例子

這里是一個基于cookies的session設置例子,session的內容直接存放在cookies中。
- CONFIG的參數(shù)就是設置一個cookie的參數(shù),設置鍵名、有效時間、HTTP Only、簽名加密等等;
- 然后在中間件里就可以讀寫ctx.session對象,將需要的字段掛上去;
- 下圖cookies里的FLB-SESSION就是在中間件中掛在ctx.session的信息;
在實際項目中,會話相關信息往往需要在服務端持久化,因此一般都會使用外部存儲來記錄session信息。
外部存儲可以是任何的存儲系統(tǒng),可以是內存數(shù)據(jù)結構,也可以是本地的文件,也可以是遠程的數(shù)據(jù)庫。
但是這不意味著我們不需要cookie了,由于http協(xié)議的無狀態(tài)特性,我們依然需要通過cookie來獲取session的標識(這里叫externalKey)。
part5 靜態(tài)資源(resource)

網(wǎng)站一般都提供靜態(tài)資源(圖片、字體、樣式表、腳本……),我們可以自己實現(xiàn)一個靜態(tài)資源服務器,但這沒必要,因為koa-static模塊封裝了這部分功能,簡單配置后,就可以正常訪問靜態(tài)資源了。
part6 模板引擎(template)
Koa-views

- 在之前的deme中,頁面都是通過ctx.body=‘string’的方式,將頁面返回到前端。
- 然而真實項目中,我們需要復用代碼,就需要用到模板引擎,就如現(xiàn)在pc項目的jsp一樣。
- Koa給需要進行視圖模板渲染的應用,提供koa-views這個中間件,這個中間件支持ejs, jade,nunjucks等眾多模板引擎。
- Koa-views的使用方法,use一下,指定模板所在的路徑就可以了。
渲染頁面時,調用ctx的render方法,傳入對應模板的路徑及數(shù)據(jù)就可以了
Why EJS

為什么我們選用的模板語言是EJS呢
主要是因為,EJS 是一套簡單的模板語言,具有以下優(yōu)點:
- 純 JavaScript:利用普通的 JavaScript 代碼生成 HTML 頁面;
- 語法簡單: EJS 支持直接在標簽內書寫簡單、直白的 JavaScript 代碼。只需讓 JavaScript 輸出你所需要的 HTML ;
- 執(zhí)行迅速:基于V8引擎,EJS 能夠緩存 JS 函數(shù)的中間代碼,從而提升執(zhí)行速度;
- 易于調試:調試 EJS 錯誤(error)很容易:所有錯誤都是普通的 JavaScript 異常,并且還能輸出異常發(fā)生的位置;
- 社區(qū)活躍: EJS 背后是一個活躍用戶組成的大規(guī)模社區(qū),能夠為 EJS 的演進提供大力支持。
當然,其他模板語言也有這樣那樣的有點,但最主要的是,因為ejs的語法與jsp類似,重構搬代碼時比較便捷,可以在編輯器寫正則替換,提高開發(fā)效率
part7 優(yōu)化與安全(optimize&safety)

因為node跑在服務器上,最后介紹幾個優(yōu)化、安全的中間件
koa-helmet 中間件增加安全HTTP頭字段。
koa-compress 壓縮啟用類似Gzip的壓縮技術減少傳輸內容
koa-logger 提供了輸出請求日志的功能,包括請求的url、狀態(tài)碼、響應時間、響應體大小等信息,對于調試和跟蹤應用程序特別有幫助
相關資料
demo地址:https://github.com/yejiayuan163/koaDemo
ppt地址:鏈接:https://pan.baidu.com/s/1Vv_LkaN9kj3IP9rOlZjuMQ 提取碼:zhxu
謝謝閱讀?。?!