如何在Node.js中开始使用HTTP/2

1,018 阅读6分钟

Node.js中的HTTP/2入门教程

在这个Node.js教程中,我们将了解HTTP/2和服务器推送,它是如何工作的,以及它对性能的影响。我们将使用Node.js来构建我们的HTTP/2服务器。

长期以来,HTTP协议一直是互联网通信的基础。它的架构主要是基于客户/服务器模式的。你建立的哪些网络应用在等待资产加载时加载时间受到影响,而提前推送这些资产会有帮助?

这就是HTTP/2旨在解决的问题,提高网络效率。它是[在2015年发布的],改进了功能,以解决HTTP/1(第一版)的限制。它使用的方法包括压缩、多路复用和优先级。

都是为了克服HTTP的开销。让我们开始吧!

前提条件

要跟上这个教程--读者将需要以下条件。

  1. 对[JavaScript]编程的基本知识是必不可少的。
  2. 你需要在你的系统上安装一个文本编辑器。我最喜欢的是[VS Code]。
  3. 在你的系统上安装一个浏览器,[如谷歌浏览器]。
  4. 在你的机器上安装好[Node.js]。

关于HTTP/2和服务器推送的简介

HTTP/2将使我们的网络应用感到更快,更简单,并使它们更强大。它使用新的技术,如多路复用连接,以消除网络的性能瓶颈。

HTTP/2的主要目标包括。

  • 通过压缩服务器的请求头来减少开销。
  • 在单个HTTP或TCP连接上执行完整的请求和响应复用。
  • 使用HTTP/2服务器推送和客户端缓存。

服务器推送是将我们对单个客户端请求的资产捆绑到一个HTTP/2响应中。我们可以提前将所有资产推送给浏览器,而不是等待浏览器首先加载HTML并确定要下载哪些资产。

在引擎盖下,所有的数据流都是通过PUSH_PROMISE ,其中包含承诺资源的HTTP头信息来启动。这将向服务器发出信号,使其在响应时间之前向客户端推送所述资源,从而避免重复请求。

设置我们的项目

首先,创建一个http2-server-push 文件夹,并在你的IDE上打开它。在http2-server-push 文件夹的根部,运行npm init -y 命令,通过生成一个初始的package.json 文件来设置一个新项目。

我们的项目将使用npm注册表中的两个依赖项。

  • express:Express是一个Node.js框架,用于构建Web应用程序和后端API。
  • spdy: spdy是一个兼容Express的模块,在Node.js中创建支持HTTP/2的服务器。
  • nodemon: nodemon是一个开发依赖模块,将自动重新启动我们的Node.js服务器。

要使用npm 安装这些软件包。

运行命令。npm install express spdy

对于devDependency nodemon包,使用命令添加它。npm install -D nodemon

大多数浏览器将不支持服务器推送功能,除非它是从一个安全的服务器上完成的。因此,我们将为我们的应用程序生成一个密钥和一个证书。

运行下面的命令来生成一个SSL证书。

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crt

对于所有的提示,点击回车,使所有的字段为空。该命令将创建一个server.crt和server.key文件。在我们的Node.js服务器脚本中,我们将从server.keyserver.crt 文件中读取。

package.json 中添加这个npmnodemon 服务器启动脚本,以便自动重新加载。

  "scripts": {
    "devStart": "nodemon server.js",
  },

我们的项目结构现在看起来像。

/http2-server-push
  node_modules/
|--- server.crt
|--- server.key
package.json
package.lock.json

使用Express和spdy实现HTTP/2和服务器推送

导入依赖项。在我们的文件夹根部创建入口index.js 文件(见上面的项目结构)。

index.js 文件内添加以下Node.js脚本。

const spdy = require("spdy")
const express = require("express")
const fs = require("fs")
const {promisify} = require("util")

const readFile = promisify(fs.readFile)

const app = express()

app.use(express.static("public"))

app.get("/push", async (req, res) => {
  try {
    if(res.push){
      [
        "/app.js",
        "/styles.css",
        "/images/image.png"
      ].forEach(async (file) => {
       res.push(file, {}).end(await readFile(`public${file}`))
      })
    }

    res.writeHead(200)
    res.end(await readFile("index.html"))
  }catch(error){
    res.status(500).send(error.toString())
  }
})

spdy.createServer(
  {
    key: fs.readFileSync("./server.key"),
    cert: fs.readFileSync("./server.crt")
  },
  app
).listen(8000, (err) => {
  if(err){
    throw new Error(err)
  }
  console.log("Listening on port 3001")
})

现在让我们来剖析一下上面的代码。

  • 使用spdy 模块,我们创建一个新的HTTP/2服务器。
  • 我们导入express包并实例化一个新的express应用程序。
  • app.use(express.static("public")) 是一个为 文件夹中的静态文件提供服务的中间。public
  • 我们的express服务器需要在我们浏览并点击"/"端点时提供所请求的index.html 文件,同时推送来自public 文件夹的所有其他文件,如图片、脚本和样式表。
  • spdy.createServer 是一个被调用的方法,用于创建我们的HTTP/2服务器并监听传入的请求,地址是 。它需要我们的应用程序的一个实例,另一个是带有我们的服务器密钥和证书的选项对象。port 3001

接下来,我们需要运行节点服务器。打开你的浏览器和开发工具,进入网络标签。在我们的应用程序中,我们正在使用一个自签名的证书来设置TLS,因此浏览器会显示一个警告。

我们需要通过点击高级来克服这个问题,并继续浏览网站。现在让我们去https://localhost:3001 ,我们的HTTP/2服务器正在运行。

在 "网络 "选项卡下,我们看到所有对我们的脚本、图像和样式表的请求都将以 "推送 "的方式从服务器接收。

http-push.

我们的应用程序的逻辑流程是这样的。

  • 客户端/浏览器将请求HTML文档文件。
  • 这个请求被我们的后端服务器接收,在发回HTML文档之前,服务器会处理这个请求。
  • 当发送/index.html ,服务器会识别更多的资源,如/app.js/styles.css ,和/images/image.png ,以便我们的索引文件被正确呈现。因此,服务器也会将这些文件与/index.html 文件一起推送。
  • 然后,浏览器将使用HTML文件及其相关资源来渲染页面。

不过,在浏览器的开发工具下,我们还是可以确认我们的应用程序使用的是第二版的HTTP协议。

http-version.

结论

每个人都知道提高我们的网络应用的速度的意义。用最少的代码,我们已经实现了一个简单的Node.js服务器,采用了HTTP/2和服务器推送。HTTP/2正在成为新的网络标准,其强大的功能不断提高网络效率,同时简化了开发的麻烦。

有了服务器推送等功能,使我们能够在等待客户端请求之前发送资产,页面加载和延迟都得到了极大的改善。