[译] Node.js, Express.js 搭建 HTTP/2 服务器
原文:Easy HTTP/2 Server with Node.js and Express.js
作者:Azat Mardan
代碼:http2-express
什么是 HTTP/2
現代互聯網的 TCP/IP 協議發布于1975年,這項技術在41年前是多么令人驚訝。自它發布開始大部分形式,我們使用 HTTP 和 后續接任者 HTTP/1.1 來實現客戶端和服務端的通訊。它能很不錯的傳輸 Web,但今時今日的開發者建立網站的方式已經發生了巨大的改變。存在各式各樣的外部資源鏈接例如圖片、CSS 文件、JavaScript 資源。資源的種類數量只會持續增長。
HTTP/2 是針對表現一直不錯的舊協議 HTTP 自從1991年發布以來這15年的第一次大的升級改動!它為優化現代瀏覽器而生。性能更加優越而且不用使用復雜的行為例如域名分片(通過多個域名發送資源)或者資源文件合并`(提供一個整合的大資源而不是多個小資源)
HTTP/2 是當前 web 的新標準,其雛形是 Google 的 SPDY 協議。當前已經被大多數主流瀏覽器支持,且很多網站已經通過該協議實現。例如訪問 Yahoo 的 Flickr 在使用的是 HTTP/2 協議(截圖時間為2016年7月).
HTTP/2 的優勢和注意事項
HTTP/2 和 HTTP/1.1 的使用沒什么區別,仍然可以在 body 中使用類 xml 的語法,使用 header 協議頭字段, 狀態碼, cookies, methods, URLs, 等等。開發者熟悉使用的東西都還可以繼續在 HTTP/2 使用。
HTTP/2的優勢如下:
多路復用傳輸(Multiplexing):允許瀏覽器在單個TCP連接中包含多個請求,從而使瀏覽器能夠并行地請求所有的資源;
服務器推送(Server push):服務器可以在瀏覽器知道需要該資源前,推送給瀏覽器(如:CSS、JS、Image),從而通過減少請求數量來加速頁面加載時間;
流傳輸優先級(Stream priority):允許瀏覽器去控制資源的加載優先級,例如,瀏覽器先請求 HTML 渲染再去加載其他的 CSS 和 JS 文件;
頭部壓縮(Header compression): HTTP/1.1 請求的頭部總是重復一樣的內容,而 HTTP/2 則強制對所有請求的頭部進行了去重壓縮;
實際的強制加密(De facto mandatory encryption):雖然加密不是硬性要求的,但是大多數瀏覽器只支持 TLS(HTTPS) 上的 HTTP/2。
雖然目前對于 HTTP/2 還不能完全滿足一些苛求,但是直到更好的技術出現以前,當前是一項明顯的技術進步。讓我們來看看,作為 Web 開發者需要了解的必要知識。大部分適用于 HTTP/1.1 的優化技巧在 HTTP/2 中變成多余的,其中一些甚至反而會影響 HTTP/2 上的網站性能,例如:
資源文件合并;
你也應該停止使用精靈圖(image sprites)、CSS和JS打包,因為只要其中一小部分有改動就會影響客戶端的緩存的作用;在 HTTP/2 協議上更好的方式是使用多個的小文件,而不是一個大文件。
作者希望前端構建工具,如 Grunt 、 Gulp 、 Webpack 將會因此特性被放棄使用,他們使 Web 開發更高的復雜度,極高的學習曲線,以及管理項目的依賴關系。
另一個適用于 HTTP/1.1 不適用于 HTTP/2 的是,域名分片(為了繞過TCP并行請求數量限制)。雖然它不一定在所有情況下有害,但對于 HTTP/2 的多路復用傳輸,這樣做也已經沒好處了。之所以建議不在 HTTP/2 使用域名分片,還因為每個域名會帶來額外的查詢負載。如果真的有需要,那么更好的方式是解析多個域名到同一個IP,而且保證你使用的是通配符證書或整合了多域名的證書,從而減少域名查詢的時間。
若想了解更多關于 HTTP/2 的介紹,可以看看官網。
Node.js 搭建 HTTP/2
現在,讓我們看看怎么通過 Node.js 搭建 HTTP/2 服務器。
部署證書
創建一個新文件夾以及自己簽發的 SSL 證書。
$ mkdir http2-express $ cd http2-express $ openssl genrsa -des3 -passout pass:x -out server.pass.key 2048 ... $ openssl rsa -passin pass:x -in server.pass.key -out server.key writing RSA key $ rm server.pass.key $ openssl req -new -key server.key -out server.csr ... Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:California ... A challenge password []: ... $ openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt當你訪問服務器的時候,因為瀏覽器默認不信任自己簽發的證書,請確保選擇 “高級” 和 “繼續訪問 localhost (不安全)” 或者將 localhost 設置成不安全訪問的例外。
初始化、依賴、入口
通過 npm ,初始化項目 package.json ,安裝依賴 spdy 和 express :
npm init npm i express spdy --save創建應用的入口文件 index.js ,主要是引用以及實例化
const port = 3000 const spdy = require('spdy') const express = require('express') const path = require('path') const fs = require('fs')const app = express()定義 Express.js 的 route
實現 Express.js 的 route
app.get('*', (req, res) => {res.status(200).json({message: 'ok'}) })設置證書以及啟動 Server
通過 fs.readFileSync() 讀取證書
const options = {key: fs.readFileSync(__dirname + '/server.key'),cert: fs.readFileSync(__dirname + '/server.crt') }然后,設置證書選項到 Express 對象:
spdy.createServer(options, app).listen(port, (error) => {if (error) {console.error(error)return process.exit(1)} else {console.log('Listening on port: ' + port + '.')}})最后,node . 啟動服務器
檢查結果
通過瀏覽器的開發者工具查看協議,就如剛剛我們查看 Yahoo 的 Flickr 協議一樣。
可以看到,使用 Node.js 和 Express.js 配合庫 node-spdy 實現 HTTP/2 簡單易懂。大多數情況下,對你的業務代碼是基本不需要修改的,想必,你的網站也已經使用了 HTTPS/SSL (除非你的服務器只提供靜態資源,否則你應該使用安全的 HTTPS/SSL ),即使是不使用 HTTP/2 你也可以替換 HTTP/1.1 而使用 SPDY
當然,在 Node.js 的大環境中,有很多的庫,不只是 node-spdy 提供 HTTP/2 實現,例如:node-http2
結語
HTTP/2 提供了更多更優的好處,而且不用使用復雜的優化技巧。開始享受 HTTP/2 給你帶來的這些好處。展望光明的未來!
PS:
本文源代碼地址在 http2-express
我的博客
總結
以上是生活随笔為你收集整理的[译] Node.js, Express.js 搭建 HTTP/2 服务器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python中dataframe数据框中
- 下一篇: 2017-08-14 前端日报