一個 HTTP 請求的一輩子

這是廢話,別看。嗯。html


今天剛看完 @樸(piáo)靈 大神的「九淺一深 Node.js」的網絡編程部分,結合本身的理解,以 Express 爲例總結一下 HTTP 服務器的機制。node

引用一下以前在這裏的一個回答嗯:express

Express 框架的 API,說白了就是鉤子鏈。編程

app.use([path, ]hook)
app.get(path[, hook1, hook2, hook3, ...], handler)

任何一個鉤子,只要調用了 res.end()(或者 res.send()res.render() 之類最終會調用 res.end() 的方法)後,就將內容返回給用戶,中斷後續的鉤子;若是調用 next() 則把請求傳遞給下一個鉤子,一直傳遞到最後的 handlersegmentfault

app.use(function (req, res, next) {
  // I'm hook 1, I won't do anything.
  next()
})

app.use(function (req, res, next) {
  // I'm hook 2, I'll break the chain
  res.send('Oops! Broke at hook 2')
})

app.get('/', function (req, res) {
  // Handler for path /
  // We responsed the user at hook 2,
  // so requests would never reach this handler
  res.send('You\'ll never see this')
})

從前,有一個寂寞的 Express 實例,它在那裏等呀等,等呀等。。。api

忽然,有一我的類,在瀏覽器輸入了一個網址,瀟灑一拍回車。而後,這個訪問請求,通過茫茫的互聯網,到達了這個寂寞的 Express 實例所在的服務器。。。瀏覽器

這個請求(一坨數據,嗯它走的是一個 TCP 鏈接),首先進入了 Node.js 的內核,通過 net 模塊,被包裝成一個特殊的 Stream。此時,它和其它 TCP 請求同樣,只是一坨二進制數據,沒人看得懂它是什麼意思。服務器

隨後,這個 Stream 到達了 http 模塊。在這裏,這條普通又不平凡的 TCP 數據流終於被解析出了 HTTP Header 並做爲屬性記錄到了這個 Stream 中,今後它做爲一個 HTTP 請求的生命就有了意義(喂!)。。。網絡

固然,這些信息對於一個成熟的 Web 服務是遠遠不夠的。因而,Express 脫好褲子(喂!夠了)等着了!app

Stream 在 Express 的身體裏流啊流,流啊流,通過了一堆中間件。它們有的從 HTTP Header 中解析出了 Cookie,並記錄到 Stream 身上;有的將縮成一坨的 POST body 解析成哈希表;有的僅僅是將這個請求的信息打印在終端上。。。可是,它們卻都掌握着這條 Stream 的生死大權,隨時能夠截斷它的流動,而後對着地球上的那我的類,丟出一條錯誤,留下一個未解之謎。

終於,通過了漫長的旅程,這條 Stream 終於到達了它的目的地——某個稱之爲程序猿的物種留下的業務邏輯。。。嗯而後就各類啪啪啪啪啪啪。。。結果一樣以 Stream 的方式返回,再次穿過那茫茫互聯網。而後,屏幕前的那個地球人,終於看到瀏覽器白底黑字恭謹地寫着幾個大字:

Hello World!

相關文章
相關標籤/搜索