1、连接方式:
http 1.0 是无状态的,每次请求都需要建立新的连接,这意味着每次请求都需要进行TCP握手,这会导致大量延迟。
http 2.0 支持多路复用,可以在一个tcp连接上并发多个请求或响应。
2、数据格式:
http 1.0 的数据是文本格式,方便阅读但不利于传输和解析。
http 2.0 的数据是二进制格式,更利于传输和解析。
3、头部压缩:
http 1.0 的请求头部信息是明文,会导致大量的冗余数据。
http 2.0 的请求头部是经过了压缩的,减少了数据传输量,并且使用了HPACK去除了冗余的头部字段。
4、服务器推送:
http 1.0 中,客户端需要明确请求服务器才能获取资源。
http 2.0 中,服务器可以主动向客户端推送资源。服务端预测到客户端需要的资源后,在客户端请求之前就将这些资源发送到客户端存储到缓存中,
等到客户端真正需要的时候,直接从缓存中获取,提高了性能。
Node.js 的 HTTP/2 服务器推送代码实例:
const http2 = require('http2');
const fs = require('fs');
const server = http2.createSecureServer({
key: fs.readFileSync('localhost-privkey.pem'),
cert: fs.readFileSync('localhost-cert.pem')
});
server.on('stream', (stream, headers) => {
// 推送资源
const pushHeaders = { ':path': '/pushed.html' };
stream.pushStream(pushHeaders, (err, pushStream) => {
pushStream.respond({ ':status': 200 });
pushStream.end('Some content to be pushed');
});
// 响应原始请求
stream.respond({ ':status': 200 });
stream.end('Hello World');
});
server.listen(8443);
应用场景示例:
假设有一个网页,它的 HTML 文件中包含了对一个 CSS 文件和一个 JavaScript 文件的引用。
当用户访问这个网页时,服务器首先会返回 HTML 文件。
在 HTTP/1.x 中,浏览器需要解析 HTML 文件,发现 CSS 文件和 JavaScript 文件的引用后,再向服务器发送请求获取这两个文件。
而在 HTTP/2 中,服务器在发送 HTML 文件的同时,可以预测到浏览器接下来会请求 CSS 文件和 JavaScript 文件,
因此,服务器可以在发送 HTML 文件的同时,将 CSS 文件和 JavaScript 文件推送到浏览器的缓存中。
这样,当浏览器解析 HTML 文件,发现需要 CSS 文件和 JavaScript 文件时,就可以直接从缓存中获取,而不需要再向服务器发送请求。
当然,这并不意味着这些资源的获取过程是不可见的。在 Chrome 浏览器的 Network 面板中,有一个叫做 "Initiator" 的列,它显示了每个请求的发起者。对于服务器推送的资源,这一列的值通常会是 "Push / Other",这表示这个资源是由服务器推送的。