Node.js中的HTTP/2入门教程
在这个Node.js教程中,我们将了解HTTP/2和服务器推送,它是如何工作的,以及它对性能的影响。我们将使用Node.js来构建我们的HTTP/2服务器。
长期以来,HTTP协议一直是互联网通信的基础。它的架构主要是基于客户/服务器模式的。你建立的哪些网络应用在等待资产加载时加载时间受到影响,而提前推送这些资产会有帮助?
这就是HTTP/2旨在解决的问题,提高网络效率。它是[在2015年发布的],改进了功能,以解决HTTP/1(第一版)的限制。它使用的方法包括压缩、多路复用和优先级。
都是为了克服HTTP的开销。让我们开始吧!
前提条件
要跟上这个教程--读者将需要以下条件。
- 对[JavaScript]编程的基本知识是必不可少的。
- 你需要在你的系统上安装一个文本编辑器。我最喜欢的是[VS Code]。
- 在你的系统上安装一个浏览器,[如谷歌浏览器]。
- 在你的机器上安装好[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.key
和server.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服务器正在运行。
在 "网络 "选项卡下,我们看到所有对我们的脚本、图像和样式表的请求都将以 "推送 "的方式从服务器接收。
.
我们的应用程序的逻辑流程是这样的。
- 客户端/浏览器将请求HTML文档文件。
- 这个请求被我们的后端服务器接收,在发回HTML文档之前,服务器会处理这个请求。
- 当发送
/index.html
,服务器会识别更多的资源,如/app.js
,/styles.css
,和/images/image.png
,以便我们的索引文件被正确呈现。因此,服务器也会将这些文件与/index.html
文件一起推送。 - 然后,浏览器将使用HTML文件及其相关资源来渲染页面。
不过,在浏览器的开发工具下,我们还是可以确认我们的应用程序使用的是第二版的HTTP协议。
.
结论
每个人都知道提高我们的网络应用的速度的意义。用最少的代码,我们已经实现了一个简单的Node.js服务器,采用了HTTP/2和服务器推送。HTTP/2正在成为新的网络标准,其强大的功能不断提高网络效率,同时简化了开发的麻烦。
有了服务器推送等功能,使我们能够在等待客户端请求之前发送资产,页面加载和延迟都得到了极大的改善。