使用NodeJS操作網絡,特別是操作HTTP請求和響應時會遇到一些驚喜,這里對一些常見問題做解答。
* 問: 為什么通過`headers`對象訪問到的HTTP請求頭或響應頭字段不是駝峰的?
答: 從規范上講,HTTP請求頭和響應頭字段都應該是駝峰的。但現實是殘酷的,不是每個HTTP服務端或客戶端程序都嚴格遵循規范,所以NodeJS在處理從別的客戶端或服務端收到的頭字段時,都統一地轉換為了小寫字母格式,以便開發者能使用統一的方式來訪問頭字段,例如`headers['content-length']`。
* 問: 為什么`http`模塊創建的HTTP服務器返回的響應是`chunked`傳輸方式的?
答: 因為默認情況下,使用`.writeHead`方法寫入響應頭后,允許使用`.write`方法寫入任意長度的響應體數據,并使用`.end`方法結束一個響應。由于響應體數據長度不確定,因此NodeJS自動在響應頭里添加了`Transfer-Encoding: chunked`字段,并采用`chunked`傳輸方式。但是當響應體數據長度確定時,可使用`.writeHead`方法在響應頭里加上`Content-Length`字段,這樣做之后NodeJS就不會自動添加`Transfer-Encoding`字段和使用`chunked`傳輸方式。
* 問: 為什么使用`http`模塊發起HTTP客戶端請求時,有時候會發生`socket hang up`錯誤?
答: 發起客戶端HTTP請求前需要先創建一個客戶端。`http`模塊提供了一個全局客戶端`http.globalAgent`,可以讓我們使用`.request`或`.get`方法時不用手動創建客戶端。但是全局客戶端默認只允許5個并發Socket連接,當某一個時刻HTTP客戶端請求創建過多,超過這個數字時,就會發生`socket hang up`錯誤。解決方法也很簡單,通過`http.globalAgent.maxSockets`屬性把這個數字改大些即可。另外,`https`模塊遇到這個問題時也一樣通過`https.globalAgent.maxSockets`屬性來處理。