摘要:每個中間件可以從實例,接收三個參數,依次為對象代表請求對象代表回應,回調函數代表下一個中間件。等方法除了在回調函數內部判斷請求的網址,方法也允許將請求網址寫在第一個參數。
前言
利用node直接實現服務器是運用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直接就能創建一個服務器的實例,然后調用實例的listen方法,傳入監聽的端口與主機就ok了,
處理函數把http的request和response對象作為兩個參數進行操作。
實現路由: 通過請求的url來判斷
寫響應頭部:res.writeHead方法
寫響應body: res.write
結束響應: 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);
監聽req的data和end事件,data事件會在數據接收過程中,每收到一段數據就觸發一次,
接收到的數據被傳入回調函數。end事件則是在所有數據接收完成后觸發。
簡單說,中間件(middleware)就是處理HTTP請求的函數。它最大的特點就是,一個中間件處理完,再傳遞給下一個中間件。
App實例在運行過程中,會調用一系列的中間件。每個中間件可以從App實例,接收三個參數,
依次為request對象(代表HTTP請求)、response對象(代表HTTP回應),next回調函數(代表下一個中間件)。
每個中間件都可以對HTTP請求(request對象)進行加工,并且決定是否調用next方法,將request對象再傳給下一個中間件。
一個不進行任何操作、只傳遞request對象的中間件,就是下面這樣。
function uselessMiddleware(req, res, next) { next(); }
上面代碼的next就是下一個中間件。如果它帶有參數,則代表拋出一個錯誤,參數為錯誤文本。
function uselessMiddleware(req, res, next) { next("出錯了!"); }
拋出錯誤以后,后面的中間件將不再執行,直到發現一個錯誤處理函數為止。
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 路由的實現 2.2.1 request.url
可以利用request.url屬性,判斷請求的網址,從而返回不同的內容,實現路由。
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等方法
除了在回調函數內部判斷請求的網址,use方法也允許將請求網址寫在第一個參數。
這代表,只有請求路徑匹配這個參數,后面的中間件才會生效。無疑,這樣寫更加清晰和方便。
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的請求中我們可以看到,需要通過監聽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提供了一下幾種轉換格式
JSON body parser
Raw body parser
Text body parser
URL-encoded form body parser
利用中間件以后,可以直接利用request.body直接獲取轉換后的body。
router.post("/testpost", function(req, res, next) { console.log("testpost"); res.send(req.body); });三、Koa框架
一個Koa應用就是一個對象,包含了一個middleware數組,這個數組由一組Generator函數組成。
這些函數負責對HTTP請求進行各種加工,比如生成緩存、指定代理、請求重定向等等。
var koa = require("koa"); var app = koa(); app.use(function *(){ this.body = "Hello World"; }); app.listen(3000);
可以看到,Koa框架和Express框架使用起來很相似。那么重點說的應該是Koa框架的不同之處:
1.中間件用Generator函數,所以中間件利用了Generator函數的中斷等待特性
2.把request和response對象封裝到了context中,通過this訪問,所以操作的api會有不同。
3.1 中間件Koa中間件與Express的不同就在于它是Generator函數,Generator函數內部使用yield命令,將程序的執行權轉交給下一個中間件,
即yield next,要等到下一個中間件返回結果,才會繼續往下執行,所以是嵌套執行的順序。
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,將控制權交給它,不必將處理邏輯寫在回調函數中。
Generator函數會返回一個遍歷器對象,yield語句就是暫停的標識,Koa框架則會自動的遍歷Generator函數,直到結束,返回http請求。
所以在何時返回http請求,koa沒有像http模塊和Express框架那樣顯示的指定,比如調用res.end,res.send等方法來結束http響應。
koa則是在執行完所有中間件以后自動的返回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請求,就會創建一個新的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);
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/82716.html
摘要:接口用于接收服務器發送的事件。因此,是目前來說最佳的選擇。最大特點就是,服務器可以主動向客戶端推送消息,客戶端也可以主動向服務器發送信息,是一種不受限的全雙工通信。若是,則交給的回調函數處理,否則,還是走正常的回調的路子。 使用 WebSocket 的理由 傳統的http協議有一個根本性的缺陷,那就是請求只能由客戶端向服務器發起,服務器接收到請求后再進行響應,把數據返回給客戶端。也就是...
摘要:是解釋性語言因服務端的應用,而貫通了前后臺。關于和聲明的變量和聲明的變量整體,會被提升到當前作用域的頂部。做后臺服務端,處理請求的代碼,得自己實現了。為提高下載速度,可通過來切換鏡像源。 JS是解釋性語言,因node服務端的應用,而貫通了前后臺。 【ES6】 關于var和let var: 1.var聲明的變量和function聲明的變量整體,會被提升到當前作用域的頂部。 2...
摘要:接上次挖的坑,對相關的源碼進行分析第一篇。和同為一批人進行開發,與相比,顯得非常的迷你。在接收到一個請求后,會拿之前提到的與來創建本次請求所使用的上下文。以及如果沒有手動指定,會默認指定為。 接上次挖的坑,對koa2.x相關的源碼進行分析 第一篇。 不得不說,koa是一個很輕量、很優雅的http框架,尤其是在2.x以后移除了co的引入,使其代碼變得更為清晰。 express和ko...
閱讀 3271·2021-11-23 10:09
閱讀 2070·2021-10-26 09:51
閱讀 985·2021-10-09 09:44
閱讀 3913·2021-10-08 10:04
閱讀 2752·2021-09-22 15:14
閱讀 3632·2021-09-22 15:02
閱讀 1071·2021-08-24 10:03
閱讀 1733·2019-12-27 12:14