准备SSL证书

  1. 生成服务器私钥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

  

  1. 生成证书请求文件CSR
1
openssl req -new -key key/server.key -out key/server.csr

  

  1. 生成证书
1
openssl x509 -req -days 3650 -in key/server.csr -signkey key/server.key -out key/server.crt

  

Node.js代码实现

  1. 新建项目
    初始化项目并安装spdy和express:
1
2
npm init -y
npm i express spdy -D

  

  1. 创建入口文件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. 读取证书
1
2
3
4
const options = {
    key: fs.readFileSync(__dirname + '/key/server.key'),
    cert: fs.readFileSync(__dirname + '/key/server.crt')
}

  

  1. 把证书传入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. 启动服务
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,而是服务端在已经知道一个页面所需要的额外的资源,并且可以在响应初始请求时开始推送这些资源。

 

几个注意点:

  1. 只能推送当前服务器上的资源,无法推送托管在CDN上的资源。
  2. 除非客户端确定需要,否则不要推送,浏览器缓存的资源不要再推送。
  3. 不要把客户端需要的所有资源的推送,根据实际情况按需推送。

参考资源

  1. HTTP/2 Push: The details
  2. HTTP/2 DEMO
  3. HTTP/2 explained

 

posted on   ygunoil  阅读(288)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示