准备SSL证书
- 生成服务器私钥key
# 生成密码文件,省去输入密码
1 2 | openssl genrsa -des3 -passout pass:123456 - out key/server.pass.key 2048 openssl rsa -passin pass:123456 - in key/server.pass.key - out key/server.key |
- 生成证书请求文件CSR
1 | openssl req - new -key key/server.key - out key/server.csr |
- 生成证书
1 | openssl x509 -req -days 3650 - in key/server.csr -signkey key/server.key - out key/server.crt |
Node.js代码实现
- 新建项目
初始化项目并安装spdy和express:
1 2 | npm init -y npm i express spdy -D |
- 创建入口文件index.js,实例化express和引入spdy
1 2 3 4 5 6 | const port = 3000 const spdy = require( 'spdy' ) const express = require( 'express' ) const path = require( 'path' ) const fs = require( 'fs' ) const app = express() |
- 读取证书
1 2 3 4 | const options = { key: fs.readFileSync(__dirname + '/key/server.key' ), cert: fs.readFileSync(__dirname + '/key/server.crt' ) } |
- 把证书传入spdy并创建服务
1 2 3 4 5 6 7 8 9 10 11 12 13 | app. get ( '/' , (req, res) => { res.end( 'hello from http/2' ) }) spdy .createServer(options, app) .listen(port, (error) => { if (error) { console.error(error) return process.exit(1) } else { console.log( 'Listening on port: ' + port + '.' ) } }) |
- 启动服务
1 | $ node index.js |
浏览器打开页面测试 https://127.0.0.1:3000, 因为我们创建的证书并没有经过CA机构认证,所以会提示页面不安全,点击继续访问即可。 查看网络请求协议可以看到网站使用了HTTP/2(h2)。

到此一个简易的基于Node.js的HTTP/2实现已经完成。 接下来我们看看HTTP/2协议中的Server Push功能。
服务端推送Server Push
为了改善延迟,HTTP/2引入了 Server Push ,这允许服务器在明确的请求之前将资源推送到浏览器。这就允许服务器充分利用空闲的网络来改善加载时间。

添加服务端推送代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | app. get ( '/' , (req, res) => { var stream = res.push( '/main.js' , { status: 200, // optional method: 'GET' , // optional request: { accept: '*/*' }, response: { 'content-type' : 'application/javascript' } }) stream. on ( 'error' , function() {}) stream.end(fs.readFileSync( './public/main.js' )) res.end(fs.readFileSync( './public/index.html' )) }) app.use( '/' , express. static (path. join (__dirname, 'public' ))) |
网络请求可以看到main.js是由推送来的。在请求头部并没有太多的请求信息,因为和HTTP1.1不同,不需要客户端发起请求获取main.js,而是服务端在已经知道一个页面所需要的额外的资源,并且可以在响应初始请求时开始推送这些资源。

几个注意点:
- 只能推送当前服务器上的资源,无法推送托管在CDN上的资源。
- 除非客户端确定需要,否则不要推送,浏览器缓存的资源不要再推送。
- 不要把客户端需要的所有资源的推送,根据实际情况按需推送。
参考资源
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗