JavaScript >> Javascript 文檔 >  >> Node.js

使用 Node.js 和 Express.js 的簡易 HTTP/2 服務器

現代互聯網及其 TCP/IP 協議始於 1975 年左右,這在 41 年前是驚人的。在它存在的大部分時間裡,我們使用 HTTP 和它的後續 HTTP/1.1(1.1 版)在客戶端和服務器之間進行通信。它很好地服務於網絡,但開發人員構建網站的方式發生了巨大變化。有無數的外部資源、圖像、CSS 文件、JavaScript 資產。資源數量只會越來越多。

HTTP2 是 15 年來對舊的 HTTP 協議的第一次重大升級(第一個 HTTP 大約是 1991 年)!它針對現代網站進行了優化。如果沒有復雜的 hack,例如域分片(具有多個域)或文件連接(具有一個大文件而不是許多小文件),性能會更好。

H2 是 Web 的新標準,最初是 Google 的 SPDY 協議。它已被許多流行網站使用,並得到大多數主流瀏覽器的支持。例如,我訪問了 Yahoo 的 Flickr,它已經在使用 h2 協議 (HTTP2)(截至 2016 年 7 月)。

雅虎的 Flickr 已經在使用 h2 協議(HTTP2)

HTTP/2 在語義上與 HTTP/1.1 沒有任何不同,這意味著您在正文中具有相同的類似 XML 的語言以及相同的標頭字段、狀態代碼、cookie、方法、URL 等。開發人員熟悉的東西仍然存在H2。 H2的好處包括:

  1. 多路復用:允許瀏覽器在單個 TCP 連接中包含多個請求,這反過來又使瀏覽器能夠並行請求所有資產。
  2. 服務器推送:服務器可以在瀏覽器知道需要之前推送網絡資源(CSS、JS、圖像),從而通過減少請求數量來加快頁面加載時間。
  3. 流優先級:允許瀏覽器指定資源的優先級。例如,瀏覽器可以先請求 HTML,然後再渲染任何樣式或 JavaScript。
  4. 標頭壓縮:所有 HTTP/1.1 請求都必須具有通常重複相同信息的標頭,而 H2 強制所有 HTTP 標頭以壓縮格式發送。
  5. 事實上的強制加密:雖然不需要加密,但大多數主流瀏覽器僅通過 TLS (HTTPS) 實現 H2。

雖然對 H2 有一些批評,但它顯然是目前的前進方向(直到我們得到更好的東西)。因此,讓我們看看作為 Web 開發人員需要了解什麼。好吧,您知道的大多數優化技巧都變得不必要了,其中一些甚至會損害網站的性能。我說的是文件連接。停止這樣做(圖像精靈、捆綁的 CSS 和 JS),因為大文件中的每個小更改都會使緩存無效。最好有很多小文件。我希望像 Grunt、Gulp 和 Webpack 這樣的構建工具的需求會因此而下降。它們給 Web 項目帶來了額外的複雜性、陡峭的學習曲線和依賴性。

優秀的開發人員在 HTTP/1.1 世界中所做的另一件事,在 H2 中會傷害到你,那就是分片(在瀏覽器中超過活動 TCP 連接限制的技巧)。好吧,它可能不會在所有情況下都受到傷害,但從現在起多路復用沒有任何好處。不要在 HTTP2 中進行域分片,因為每個域都會產生額外的開銷。如果必須,則將域解析為相同的 IP,並確保您的證書具有通配符,使其對子域有效或具有多域證書。

有關 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

當您將訪問您的服務器時,請確保選擇“高級”和“繼續到本地主機(不安全)”或添加本地主機作為例外。原因是瀏覽器默認不信任自簽名證書。

點擊高級

但這是你的證書,所以可以繼續。

點擊 Proceed to localhost (unsafe)

然後,我們需要初始化package.json 並下載 spdyexpress

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 路由:

app.get('*', (req, res) => {
    res
      .status(200)
      .json({message: 'ok'})
})

然後,我們需要加載密鑰和證書文件。這可能是我們可以使用 fs.readFileSync() 的少數情況之一 :

const options = {
    key: fs.readFileSync(__dirname + '/server.key'),
    cert:  fs.readFileSync(__dirname + '/server.crt')
}

最後,我們將 SSL 選項與 Express 實例一起加載到我們的服務器中:

[旁注]

閱讀博客文章很好,但觀看視頻課程更好,因為它們更具吸引力。

許多開發人員抱怨 Node.js 上缺乏負擔得起的高質量視頻材料。觀看 YouTube 視頻會讓人分心,花 500 美元購買 Node 視頻課程很瘋狂!

去看看 Node University,它有關於 Node 的免費視頻課程:node.university。

[旁注結束]

spdy
  .createServer(options, app)
  .listen(port, (error) => {
    if (error) {
      console.error(error)
      return process.exit(1)
    } else {
      console.log('Listening on port: ' + port + '.')
    }
  })

當你用 node . 啟動服務器時 ,您可以發出 CURL 請求(確保您獲得了最新版本 7.46 和 nghttp2 ) 與 curl https://localhost:3000/ -k 查看響應(-k 是讓 CURL 可以使用自簽名證書)。

將 CURL 與 h2 一起使用

另一種檢查我們是否擁有 H2 的方法是使用 DevTools,就像我們在本文開頭使用 Flickr 所做的那樣。

在 DevTools 中檢查 H2

而已。如您所見,使用 Node.js 和 Express.js 構建 HTTP2 服務器非常簡單。在大多數情況下,您不需要進行很多更改。最有可能的是,您已經在使用 HTTPS/SSL(如果不是,那麼您應該使用,除非您的服務器僅用於靜態資產)。然後,你需要交換你的 https 對於 spdy .

還有另一個 H2 庫,稱為 http2 ,但它不適用於最新版本的 Express。您可以使用 http2 沒有 Express 或者只是等待 Express v5。

最後,HTTP/2 提供了更多好處,並消除了一些 Web 優化技巧的複雜性。現在開始通過在您的服務器中實現 H2 來獲得回報。邁向光明的未來!

PS:工作 HTTP/2 Express.js 服務器的源代碼在 github.com/azat-co/http2-express 存儲庫中。


Tutorial JavaScript 教程
  1. 什麼是 ArrayBuffer 以及如何轉換其內容?

  2. 20 多個 2020 年最佳 React UI 組件庫/框架

  3. 異步生成器類卡在無限循環javascript上

  4. 如何在 nextjs 中將對像作為道具傳遞

  5. xmlhttprequest responsetext 來自 Accept 標頭: text/xml ,但應用程序/JSON 的服務器錯誤

  6. 如何使用 React hooks 去抖動和限制函數

  7. 如何使用 Github Actions 將您的 Github 個人資料自述文件與您的最新博客文章自動化

  1. 反應.memo ()

  2. 答案:如何在 NodeJS 中的 URL 中傳遞變量

  3. 在 typescript 中拆分字符串的 3 種不同方法

  4. Angular 中的 ContentChild 和 ContentChildren

  5. 是否可以向 window.scrollTo 添加持續時間和緩動?

  6. JavaScript filter() 方法

  7. Codecrumbs - 一種學習和記錄源代碼的新方法

  1. 使用 Next.js、Airtable、Auth0 和 Tailwind CSS 構建經過身份驗證的 JAMstack 應用程序

  2. 如何組織大型 React 應用程序並使其可擴展

  3. jQuery、AJAX 和 CSS 的花哨報價

  4. 從頭開始創建 Netflix 克隆:JavaScript PHP + MySQL 第 42 天