Ⅰ Koa 學習總結
Koa是基於Node.js的下一代web框架,由Express團隊打造,特點:優雅、簡潔、靈活、體積小。幾乎所有功能都需要通過中間件實現。
即便沒有給ctx.body 設置響應數據,或訪問不存在的路由,頁面也會顯示Not Found,這是koa底層做了處理,不像原生Node或Express一樣頁面會一直處於響應狀態。
Koa將Node的request 和 response對象都封裝到了context中,每次請求都會創建一個ctx,並且在中間件中作為接收器使用。
以下是剛才訪問時的ctx對象
即便使用ctx.res.write()也不會得到預期結果,比如:ctx.res.write('hello'),結果是hellook,會把message的值拼接上。
有關cookie和session單獨介紹用法。
Koa中的路由和Express不同,Express是把路由集成在Express中,Koa則需要通過kao-router模塊使用。
Koa最大的特色和最優的設計就是中間件,就是在匹配路由之前和匹配路由之後執行函數。
使用app.use()載入中間件。每個中間件接收兩個參數,ctx對象和next函數,通過調用next將執行權交給下一個中間件。
中間件分為:
對於諸如js、css、img等靜態資源採用koa-static中間件處理。
比如靜態目錄為static:
在模板中即可訪問:
koa生態的模板引擎挺多的,比如ejs、art-template等。
使用方式和ejs一樣。
性能上相比,art-template比ejs快很多,開發中用的最多的還是art-template。
http是無狀態、無連接的。不會對之前發生過的請求和相應狀態進行管理團物。也就是說,無法根據之前的狀態進行本塌喊液次的請求處理。
比如訪問淘寶首頁並登錄賬號後,當再打開淘寶其他頁面時,因為每一次的訪問都是獨立的,伺服器並不知道你已經登錄,所以還是不能下單或者加購物車之類的操作。
cookie是客戶端第一次訪問伺服器的時候,伺服器在下行HTTP報文時通過響應頭的 set-cookie 欄位給瀏覽器分配的一個具有特殊標識的文本信息,此後當客戶端再次訪問同一域名時,便會將該欄位通過請求頭攜帶到伺服器。注意: 第一次訪問伺服器是不可能攜帶cookie的。
缺陷: 1、cookie的數據存放在客戶端,不安全,容易被(CSRF)跨站請求偽造。攻擊者可以藉助受害者的 Cookie 騙取伺服器的信任,可以在受害者毫不知情的情況下以受害者名義偽造請求發送給受攻擊伺服器,從而在並未授權的情況下執行在許可權保護之下的操作。2、單個cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie。
通過 options 獲取 cookie name:
通過 options 設置 cookie name 的 value:
通過buffer轉成base64存進去,取出來是再轉回中文。
session是另一種記錄客戶狀態的機制,不同的是cookie保存在客戶端瀏覽器中,而session保存在伺服器上。
前面說過,cookie 是存放在客戶端,不是很安全,用戶可以自己手動把cookie種在客戶端以欺騙伺服器。而session是存儲在服務滲櫻端的,所以對於較重要的數據存儲在session。
缺點: session會在一定時間內保存在伺服器上。當訪問增多,會比較佔用你伺服器的性能。
當瀏覽器第一次請求伺服器時,伺服器端會創建一個session對象,生成一個類似於key-value的鍵值對, 然後將key(cookie)下發到客戶端,當客戶端再訪問時,攜帶key(cookie),找到對應的session(value)。 生產中用戶的信息都保存在session中。
以上配置選項常用的就是key、maxAge、httpOver。
renew應用:比如我們登錄賬號寫一篇博客,寫了一半cookie過期了,當我們提交的時候就會退出登錄,體驗很不好,而且寫好的博客丟失。
301和302重定向狀態碼區別。302為臨時重定向,301永久重定向。Koa中默認為302。詳細信息查看這篇博客 301和302重定向介紹
字元串 「back」 是特別提供Referrer支持的,當Referrer不存在時,使用 alt 或「/」。
要更改 「302」 的默認狀態,只需在該調用之前或之後分配狀態。要變更主體請在此調用之後:
解決跨域的方式有很多種,個人認為最好的方案是在伺服器端設置支持跨域。
下面詳細說明在koa2中設置具體的請求頭信息:
在koa2中,解決跨域請求還可使用中間件 koa2-cors
node 發送郵件可以使用 nodemailer 三方模塊。
安裝:
使用說明:
更多詳細配置信息及功能參照 官網
Ⅱ koa-基於node.js平台的下一代web開發框架入門
koa 是由 Express 原班人馬打造的,致力於成為一個更小、更富有表現力、更健壯的 Web 框架。使用 koa 編寫 web 應用,通過組合不同的 generator,可以免除重復繁瑣的回調函數嵌套,並極大地提升錯誤處理的效率。koa 不在內核方法中綁定任何中間件,它僅僅提供了一個輕量優雅的函數庫,使得編寫 Web 應用變得得心應手。
Koa需要 node v7.6.0或更高版本來支持ES2015、非同步方法
你可以安裝自己支持的node版本。
在node < 7.6的版本中使用async 函數, 我們推薦使用babel's require hook.
為了解析和轉譯非同步函數,你應該至少有transform-async-to-generator or transform-async-to-mole-method這2個插件。例如,在你的.babelrc文件中,應該有如下代碼
也可以使用env preset並設置"node": "current"來替代.
Koa 應用是一個包含一系列中間件 generator 函數的對象。 這些中間件函數基於 request 請求以一個類似於棧的結構組成並依次執行。 Koa 類似於其他中間件系統(比如 Ruby's Rack 、Connect 等), 然而 Koa 的核心設計思路是為中間源哪枝件層提供高級語法糖封裝,以增強其互用性和健壯性,並使得編寫中間件變得相當有趣。
Koa 包緩伏含了像 content-negotiation(內容協商)、cache freshness(緩存刷新)、proxy support(代理支持)和 redirection(重定向)等常用任務方法。 與提供龐大的函數支持不同,Koa只包含很小的一部分,因為Koa並不綁定任何中間件。
任何教程都是從 hello world 開始的,Koa也不例外^_^:
Koa 的中間件通過一種更加傳統(您也許會很熟悉)的方式進行級聯,摒棄雹敏了以往 node 頻繁的回調函數造成的復雜代碼邏輯。 然而,使用非同步函數,我們可以實現"真正" 的中間件。與之不同,當執行到 yield next 語句時,Koa 暫停了該中間件,繼續執行下一個符合請求的中間件('downstrem'),然後控制權再逐級返回給上層中間件('upstream')。
下面的例子在頁面中返回 "Hello World",然而當請求開始時,請求先經過 x-response-time 和 logging 中間件,並記錄中間件執行起始時間。 然後將控制權交給 reponse 中間件。當一個中間件調用next()函數時,函數掛起並控制項傳遞給定義的下一個中間件。在沒有更多的中間件執行下游之後,堆棧將退出,並且每個中間件被恢復以執行其上遊行為。
應用配置是 app 實例屬性,目前支持的配置項如下:
Koa 應用並非是一個 1-to-1 表徵關系的 HTTP 伺服器。 一個或多個Koa應用可以被掛載到一起組成一個包含單一 HTTP 伺服器的大型應用群。
如下為一個綁定3000埠的簡單 Koa 應用,其創建並返回了一個 HTTP 伺服器,為 Server#listen() 傳遞指定參數(參數的詳細文檔請查看nodejs.org)。
The app.listen(...) 實際上是以下代碼的語法糖:
這意味著您可以同時支持 HTTPS 和 HTTPS,或者在多個埠監聽同一個應用。
返回一個適合 http.createServer() 方法的回調函數用來處理請求。 您也可以使用這個回調函數將您的app掛載在 Connect/Express 應用上。
為應用添加指定的中間件,詳情請看 Middleware
設置簽名cookie密鑰。
該密鑰會被傳遞給KeyGrip, 當然,您也可以自己生成 KeyGrip. 例如:
在進行cookie簽名時,只有設置 signed 為 true 的時候,才會使用密鑰進行加密:
app.context是從中創建ctx的原型。 可以通過編輯app.context向ctx添加其他屬性。當需要將ctx添加到整個應用程序中使用的屬性或方法時,這將會非常有用。這可能會更加有效(不需要中間件)和/或更簡單(更少的require()),而不必擔心更多的依賴於ctx,這可以被看作是一種反向模式。
例如,從ctx中添加對資料庫的引用:
注:
默認情況下Koa會將所有錯誤信息輸出到 stderr, 除非 app.silent 是 true.當err.status是404或者err.expose時,默認錯誤處理程序也不會輸出錯誤。要執行自定義錯誤處理邏輯,如集中式日誌記錄,您可以添加一個"錯誤"事件偵聽器:
如果錯誤發生在 請求/響應 環節,並且其不能夠響應客戶端時,Contenxt 實例也會被傳遞到 error 事件監聽器的回調函數里。
當發生錯誤但仍能夠響應客戶端時(比如沒有數據寫到socket中),Koa會返回一個500錯誤(Internal Server Error)。 無論哪種情況,Koa都會生成一個應用級別的錯誤信息,以便實現日誌記錄等目的。
Koa Context 將 node 的 request 和 response 對象封裝在一個單獨的對象裡面,其為編寫 web 應用和 API 提供了很多有用的方法。 這些操作在 HTTP 伺服器開發中經常使用,因此其被添加在上下文這一層,而不是更高層框架中,因此將迫使中間件需要重新實現這些常用方法。
context 在每個 request 請求中被創建,在中間件中作為接收器(receiver)來引用,或者通過 this 標識符來引用:
許多 context 的訪問器和方法為了便於訪問和調用,簡單的委託給他們的 ctx.request 和 ctx.response 所對應的等價方法, 比如說 ctx.type 和 ctx.length 代理了 response 對象中對應的方法,ctx.path 和 ctx.method 代理了 request 對象中對應的方法。
Ⅲ express和koa的區別
express和koa從整體上來看,koa是比express更加輕量,他沒有內置的各種中間件的支持,更集中於請求處理。當然在express 4.0以後,也移除了一批中間件支持,向輕量化進發。這一點上差別其實不是特別大了。
最大的差別是中間件和回調的處理邏輯。express採用的是callback,koa採用的是async,這樣在執行上鉛者賀express的callback中就天然不支持非同步的處理,在express中處理非同步可能不是你想要的執行順序。在這里,就有了koa的經典:洋蔥模型。
除此之外,koa在響應上添加了上下文的概念,使用ctx存儲各種響應信息,避免直接操作res。ctx能更好的幫助我們在多層級處理中傳遞信息,例如ctx.body可以多層級進行組合返回數槐派據。
express 3 -> 4 之後,移除了一大批中間件,其中和我們關系比較大的是bodyParser、compress、cookieSession、cookieParser、static、directory等。
除此之外,4改變了路由注冊的方式(增量式),嫌談增加了app.route、router = express.Router()的方式,中間件的app.use也支持path的注冊。詳見 Moving to Express 4 。
傳送門
express和koa的區別
Ⅳ 如何優雅的在 koa 中處理錯誤
使用中間件統一處理錯誤
有了上面的說明,那現在我們就來看看在 koa 裡面怎麼優雅的實現統一錯誤處理。
答案就是使用強大的中間件!
我們可以在業務邏輯中間件(一般就是 MVC 中的 Controller)開始之前定義下面的中間件:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
app.use(function* (next) {
try {
yield* next;
} catch(e) {
let status = e.status || 500;
let message = e.message || '伺服器錯誤';
if (e instanceof JsonError) { // 錯誤是 json 錯誤
this.body = {
'status': status,
'message': message
};
if (status == 500) {
// 觸發 koa 統一錯誤事件,可以列印出詳細的錯誤堆棧 log
this.app.emit('error', e, this);
}
return;
}
this.status = status;
// 根據 status 渲染不同的頁面
if (status == 403) {
this.body = yield this.render('403.html', {'err': e});
}
if (status == 404) {
this.body = yield this.render('404.html', {'err': e});
}
if (status == 500) {
this.body = yield this.render('500.html', {'err': e});
// 觸發 koa 統一錯誤事件,可以列印出詳細的錯誤堆棧 log
this.app.emit('error', e, this);
}
}
});
可以看到,我們直接執行 yield* next,然後 catch 執行過程中任何一個中間件的錯誤,然後根據錯誤的「特性」,分別進行不同的處理。
有了這個中間件,我們的業務邏輯 controller 中的代碼就可以這樣來觸發錯誤:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
const router = new (require('koa-router'));
router.get('/some_page', function* () {
// 直接拋出錯誤,被中間件捕獲後當成 500 錯誤
throw new PageError('發生了一個致命錯誤');
throw new JsonError('發送了一個致命錯誤');
// 帶 status 的錯誤,被中間件捕獲後特殊處理
this.throw(403, new PageError('沒有許可權訪問'));
this.throw(403, new JsonError('沒有許可權訪問'));
});
對 Error 分類
上面的代碼裡面出現的 JsonError、PageError,實際上是繼承於 Error 的兩個構造器。代碼如下:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const util = require('util');
exports.JsonError = JsonError;
exports.PageError = PageError;
function JsonError(message) {
Error.call(this, message);
}
util.inherits(JsonError, Error);
function PageError(message) {
Error.call(this, message);
}
util.inherits(PageError, Error);
通過繼承 Error 構造器,我們可以將錯誤進行細分,從而能更精細的對錯誤進行處理。
Ⅳ nodejs-koa2(mvc模式)前後端分離 前端設計
前後端分離,前端nodejs運行環境,使用koa2集成負責資源分配與用戶交互,實現token驗證用戶身份,路由控制。等!
自行 網路 解決;
"program": "${workspaceFolder}app.js"
此處就是是將app.js作為啟動文件。${workspaceFolder}代表根目錄,vsc啟動時會在根目錄下找到並載入app.js文件。
參數介紹: name 項目名稱、 version 版本號、 description 項目描述、 main 項目啟動文件、 scripts 啟動快捷設置, author 作者, dependencies 第3方中間件名稱及版本。
最重要的
「 dependencies 」這里添加一些要用到的包,以上是這次要用到的所有的包,版本自己更改。
「 scripts 」這里是一些nodejs的便捷命令,上線的時候會用到,直接在終端中,package.json同級目錄 ,執行『npm start』 即 可啟動app.js。
別的沒啥太大作用瞎寫即可。
啟動相關配置,封裝到config/init.js中,啟動文件直接引用即可
3-6-1、init.js項目核心。
異常友好處理方法封裝
路由配置
視圖渲染
核心集成
3-6-2、config.js項目參數配置。為什麼不用json文件 因為json不能加註釋
3-6-3、token.js項目token相關方法封裝。
執行後項目結構會增加兩個文件
新增
src/hello.js。
views/index.html
瀏覽器訪問: http://127.0.0.1:3000/koa/login
輸入值獲取token
獲取的token如圖:
先不用帶token進行訪問: http://127.0.0.1:3000/koa/ hello/jiaobaba,被token攔截,返回401
帶上token訪問: http://127.0.0.1:3000/koa/ hello/jiaobaba
測試頁面渲染,及跳轉html頁面,直接訪問 http://127.0.0.1:3000/koa /views
結束!!!!!!
需要源碼聯系我