Express基本原理

Express官網說:Express是基于 Node.js 平臺的 web 開發框架。這句話包含了兩個部分內容,一是Express基于Node.js平臺,二是Express是一個web開發框架。說的更直白一些意思就是,使用Express以后,底層工作的還是Node.js;即使不用Express,也完全可以搞web開發,用了Express只是會讓web開發變得更簡單一些。Node.js是從0到1,Experss是從1到10。

不使用任何開發框架,只用Node.js如何實現一個web服務

const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World!');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

Node.js自帶的http模塊做了很多工作,和操作系統打交道,監聽3000端口,每當有http請求到達3000端口時,構造request和response對象,調用創建server對象時傳給 http.createServer的回調函數并將request和response分別用參數req和res傳入。在回調函數中,在req中取得http請求相關輸入信息,經過處理后,調用res的方法將結果輸出。

使用Express以后的情形

使用Express實現的web服務,代碼和上面的純Node.js版差不多:

const express = require('express')
const app = express()

const hostname = '127.0.0.1'
const port = 3000

app.use(function (req, res, next) {
  res.statusCode = 200
  res.setHeader('Content-Type', 'text/plain')
  res.end('Hello World!')
})

app.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
})

除了最開始引用的包不同以外,唯一的區別就是請求處理回調函數的使用方式,Node.js用http.createServer,Experss用app.use
Express版的回調函數中,req和res其實就是Node.js傳入的,Node.js版req和res對象的方法、屬性在Express中都能用,Express還額外為req和res對象添加了一些方法,更加簡化web開發。
最后的listen方法參數也完全一樣,因為Express的app.listen方法只是簡單地把參數全部傳給Node.js的server.listen方法。

Express的核心,中間件

從上面的兩個Hello World示例程序回到現實世界,現實中我們總是要對不同的url使用單獨的處理邏輯,如果不用框架而只使用純Node.js的方式,無疑會非常復雜低效,代碼大概就會像這樣:

const server = http.createServer((req, res) => {
  if(req.url == '/') {
  //處理/
  } else if (req.url === '/products') {
  //處理/products
  } else if (...) {}
  //更多分支...
});

Express解決這個問題的辦法,是使用中間件。一個用Express開發的web服務,本質上就是對一系列中間件的順序調用。中間件非常簡單,就是一些函數,這些函數可以執行任何代碼,只需符合簡單的約定即可:
接受3個參數(錯誤處理中間件是4個參數,不過這個小差異不影響對Experss中間件本質的理解),req,res,next。req是請求對象,可以從這個對象中讀取所有關于http請求的信息,如header,querystring,body等;res是響應對象,可以通過調用res的方法將處理結果輸出到http response;next是一個函數,如果當前中間件沒有終結請求-響應循環,則必須調用 next() 方法將控制權交給下一個中間件,否則請求就會掛起。

只要符合這個約定的函數,都可以作為中間件,“掛載(mount)”到整個web應用程序或某一個特定的url和method上,Express在處理一個http 請求時,會從所有已掛載的中間件中,根據http 請求的輸入信息(url、method)找出所有符合條件的中間件并按順序執行,先掛載的先執行。

理解了這個本質,官方文檔讀起來就游刃有余了:
中間件文檔英文版
中間件文檔中文版

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,983評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,772評論 3 422
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,947評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,201評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,960評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,350評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,406評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,549評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,104評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,914評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,089評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,647評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,340評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,753評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,007評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,834評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,106評論 2 375

推薦閱讀更多精彩內容