摘要:每個中間件可以從實例,接收三個參數(shù),依次為對象代表請求對象代表回應,回調(diào)函數(shù)代表下一個中間件。等方法除了在回調(diào)函數(shù)內(nèi)部判斷請求的網(wǎng)址,方法也允許將請求網(wǎng)址寫在第一個參數(shù)。
前言
利用node直接實現(xiàn)服務器是運用http模塊,Express和Koa都是在其上做的封裝,
這篇wiki只是想直觀的看看封裝前后基本使用上的不同,先不去考慮深入的東西。
var http = require("http"); http.createServer(function(req, res) { // 主頁 if (req.url == "/") { res.writeHead(200, { "Content-Type": "text/html" }); res.write("Welcome to the homepage!"); res.end("Welcome to the homepage!"); } // About頁面 else if (req.url == "/about") { res.writeHead(200, { "Content-Type": "text/html" }); res.end("Welcome to the about page!"); } // 404錯誤 else { res.writeHead(404, { "Content-Type": "text/plain" }); res.end("404 error! File not found."); } }).listen(8080, "localhost");
http模塊的createServer直接就能創(chuàng)建一個服務器的實例,然后調(diào)用實例的listen方法,傳入監(jiān)聽的端口與主機就ok了,
處理函數(shù)把http的request和response對象作為兩個參數(shù)進行操作。
實現(xiàn)路由: 通過請求的url來判斷
寫響應頭部:res.writeHead方法
寫響應body: res.write
結(jié)束響應: res.end
1.2 處理Post請求var http = require("http"); http.createServer(function (req, res) { var content = ""; req.on("data", function (chunk) { content += chunk; }); req.on("end", function () { res.writeHead(200, {"Content-Type": "text/plain"}); res.write("You"ve sent: " + content); res.end(); }); }).listen(8080);
監(jiān)聽req的data和end事件,data事件會在數(shù)據(jù)接收過程中,每收到一段數(shù)據(jù)就觸發(fā)一次,
接收到的數(shù)據(jù)被傳入回調(diào)函數(shù)。end事件則是在所有數(shù)據(jù)接收完成后觸發(fā)。
簡單說,中間件(middleware)就是處理HTTP請求的函數(shù)。它最大的特點就是,一個中間件處理完,再傳遞給下一個中間件。
App實例在運行過程中,會調(diào)用一系列的中間件。每個中間件可以從App實例,接收三個參數(shù),
依次為request對象(代表HTTP請求)、response對象(代表HTTP回應),next回調(diào)函數(shù)(代表下一個中間件)。
每個中間件都可以對HTTP請求(request對象)進行加工,并且決定是否調(diào)用next方法,將request對象再傳給下一個中間件。
一個不進行任何操作、只傳遞request對象的中間件,就是下面這樣。
function uselessMiddleware(req, res, next) { next(); }
上面代碼的next就是下一個中間件。如果它帶有參數(shù),則代表拋出一個錯誤,參數(shù)為錯誤文本。
function uselessMiddleware(req, res, next) { next("出錯了!"); }
拋出錯誤以后,后面的中間件將不再執(zhí)行,直到發(fā)現(xiàn)一個錯誤處理函數(shù)為止。
use是express注冊中間件的方法。
app.use(function(request, response, next) { console.log("In comes a " + request.method + " to " + request.url); next(); }); app.use(function(request, response) { response.writeHead(200, { "Content-Type": "text/plain" }); response.end("Hello world! "); });2.2 路由的實現(xiàn) 2.2.1 request.url
可以利用request.url屬性,判斷請求的網(wǎng)址,從而返回不同的內(nèi)容,實現(xiàn)路由。
app.use(function(request, response, next) { if (request.url == "/") { response.writeHead(200, { "Content-Type": "text/plain" }); response.end("Welcome to the homepage! "); } else { next(); } }); app.use(function(request, response, next) { if (request.url == "/about") { response.writeHead(200, { "Content-Type": "text/plain" }); } else { next(); } });2.2.2 use等方法
除了在回調(diào)函數(shù)內(nèi)部判斷請求的網(wǎng)址,use方法也允許將請求網(wǎng)址寫在第一個參數(shù)。
這代表,只有請求路徑匹配這個參數(shù),后面的中間件才會生效。無疑,這樣寫更加清晰和方便。
app.use("/home", function(request, response, next) { response.writeHead(200, { "Content-Type": "text/plain" }); response.end("Welcome to the homepage! "); });
針對不同的請求,use可以有不同的別名,分別對應http的方法,包括get post put post delete。
2.2.3 利用Express.Routervar router = express.Router(); router.get("/", function(req, res) { res.send("首頁"); }); router.get("/about", function(req, res) { res.send("關于"); }); app.use("/", router);
router能夠自由掛載和直接把路由寫在use上相比,能夠為程序書寫帶來更大的靈活性。
2.3 處理POST請求為什么要多帶帶說這個post請求,因為獲取request的body不是能夠通過request的一個body屬性就可以的,
通過http處理post的請求中我們可以看到,需要通過監(jiān)聽request的data和end方法進行拼接,因為body可能分多次傳過來。
利用框架的好處就是有人寫了中間件,可以直接用。Express中處理body的中間件用body-parser
var bodyParser = require("body-parser"); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false }));
body-parser提供了一下幾種轉(zhuǎn)換格式
JSON body parser
Raw body parser
Text body parser
URL-encoded form body parser
利用中間件以后,可以直接利用request.body直接獲取轉(zhuǎn)換后的body。
router.post("/testpost", function(req, res, next) { console.log("testpost"); res.send(req.body); });三、Koa框架
一個Koa應用就是一個對象,包含了一個middleware數(shù)組,這個數(shù)組由一組Generator函數(shù)組成。
這些函數(shù)負責對HTTP請求進行各種加工,比如生成緩存、指定代理、請求重定向等等。
var koa = require("koa"); var app = koa(); app.use(function *(){ this.body = "Hello World"; }); app.listen(3000);
可以看到,Koa框架和Express框架使用起來很相似。那么重點說的應該是Koa框架的不同之處:
1.中間件用Generator函數(shù),所以中間件利用了Generator函數(shù)的中斷等待特性
2.把request和response對象封裝到了context中,通過this訪問,所以操作的api會有不同。
3.1 中間件Koa中間件與Express的不同就在于它是Generator函數(shù),Generator函數(shù)內(nèi)部使用yield命令,將程序的執(zhí)行權(quán)轉(zhuǎn)交給下一個中間件,
即yield next,要等到下一個中間件返回結(jié)果,才會繼續(xù)往下執(zhí)行,所以是嵌套執(zhí)行的順序。
app.use(function *(next){ console.log(">> one"); yield next; console.log("<< one"); }); app.use(function *(next){ console.log(">> two"); this.body = "two"; console.log("<< two"); });
輸出:
>> one >> two << one << two
所以當需要有異步操作的時候,我們可以用yield,將控制權(quán)交給它,不必將處理邏輯寫在回調(diào)函數(shù)中。
Generator函數(shù)會返回一個遍歷器對象,yield語句就是暫停的標識,Koa框架則會自動的遍歷Generator函數(shù),直到結(jié)束,返回http請求。
所以在何時返回http請求,koa沒有像http模塊和Express框架那樣顯示的指定,比如調(diào)用res.end,res.send等方法來結(jié)束http響應。
koa則是在執(zhí)行完所有中間件以后自動的返回http請求。不會等待未完成的異步操作
3.2路由兩種方式
一種是用this.path做判斷
let koa = require("koa") let app = koa() // normal route app.use(function* (next) { if (this.path !== "/") { return yield next } this.body = "hello world" });
一種是用koa-router插件,類似于Express的use和一系列http動詞方法。
var app = require("koa")(); var Router = require("koa-router"); var myRouter = new Router(); myRouter.get("/", function *(next) { this.response.body = "Hello World!"; }); app.use(myRouter.routes()); app.listen(3000);3.3 context對象
中間件當中的this表示上下文對象context,代表一次HTTP請求和回應,即一次訪問/回應的所有信息,都可以從上下文對象獲得。
context對象封裝了request和response對象,并且提供了一些輔助方法。每次HTTP請求,就會創(chuàng)建一個新的context對象。
context對象的全局屬性。
request:指向Request對象
response:指向Response對象
req:指向Node的request對象
req:指向Node的response對象
app:指向App對象
state:用于在中間件傳遞信息。
3.4 處理Post的請求其實就是如何獲取reauest中的body,利用中間件co-body,處理后可以通過this.request.body訪問
// application/json var body = yield parse.json(this); // application/x-www-form-urlencoded var body = yield parse.form(this); // text/plain var body = yield parse.text(this);
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/82716.html
摘要:接口用于接收服務器發(fā)送的事件。因此,是目前來說最佳的選擇。最大特點就是,服務器可以主動向客戶端推送消息,客戶端也可以主動向服務器發(fā)送信息,是一種不受限的全雙工通信。若是,則交給的回調(diào)函數(shù)處理,否則,還是走正常的回調(diào)的路子。 使用 WebSocket 的理由 傳統(tǒng)的http協(xié)議有一個根本性的缺陷,那就是請求只能由客戶端向服務器發(fā)起,服務器接收到請求后再進行響應,把數(shù)據(jù)返回給客戶端。也就是...
摘要:是解釋性語言因服務端的應用,而貫通了前后臺。關于和聲明的變量和聲明的變量整體,會被提升到當前作用域的頂部。做后臺服務端,處理請求的代碼,得自己實現(xiàn)了。為提高下載速度,可通過來切換鏡像源。 JS是解釋性語言,因node服務端的應用,而貫通了前后臺。 【ES6】 關于var和let var: 1.var聲明的變量和function聲明的變量整體,會被提升到當前作用域的頂部。 2...
摘要:接上次挖的坑,對相關的源碼進行分析第一篇。和同為一批人進行開發(fā),與相比,顯得非常的迷你。在接收到一個請求后,會拿之前提到的與來創(chuàng)建本次請求所使用的上下文。以及如果沒有手動指定,會默認指定為。 接上次挖的坑,對koa2.x相關的源碼進行分析 第一篇。 不得不說,koa是一個很輕量、很優(yōu)雅的http框架,尤其是在2.x以后移除了co的引入,使其代碼變得更為清晰。 express和ko...
摘要:系列種優(yōu)化頁面加載速度的方法隨筆分類中個最重要的技術(shù)點常用整理網(wǎng)頁性能管理詳解離線緩存簡介系列編寫高性能有趣的原生數(shù)組函數(shù)數(shù)據(jù)訪問性能優(yōu)化方案實現(xiàn)的大排序算法一怪對象常用方法函數(shù)收集數(shù)組的操作面向?qū)ο蠛驮屠^承中關鍵詞的優(yōu)雅解釋淺談系列 H5系列 10種優(yōu)化頁面加載速度的方法 隨筆分類 - HTML5 HTML5中40個最重要的技術(shù)點 常用meta整理 網(wǎng)頁性能管理詳解 HTML5 ...
閱讀 3227·2021-11-23 10:09
閱讀 2063·2021-10-26 09:51
閱讀 979·2021-10-09 09:44
閱讀 3906·2021-10-08 10:04
閱讀 2745·2021-09-22 15:14
閱讀 3624·2021-09-22 15:02
閱讀 1056·2021-08-24 10:03
閱讀 1727·2019-12-27 12:14