https与http2

https与http2

二月 22, 2024

https与http2

背景

  • 由于浏览器为了避免网络阻塞和资源竞争,对于同一域名下的并发请求有数量上的限制。例如对于fetch请求的并发数量,不同浏览器在同一域名下的并发请求数量通常在 4 到 8 之间。这意味着如果同时发起多个请求,只有部分请求会被处理,其他的请求会被阻塞,直到有空闲的连接可用。
  • 浏览器的并发限制是基于 HTTP/1.1 协议的,该协议规定每个 TCP 连接只能处理一个请求,而且请求必须按顺序返回。这导致了一些性能问题,比如队首阻塞(head-of-line blocking)。
  • 为了解决这些问题,HTTP/2 协议引入了多路复用(multiplexing)的特性,允许在一个 TCP 连接上同时发送多个请求,并且可以乱序返回。这样就可以减少 TCP 连接的数量,提高并发能力,避免队首阻塞。
  • 同时虽然HTTP/2 协议本身不强制要求与 HTTPS 结合使用,它支持明文传输。然而,几乎所有的主流浏览器都只在安全的上下文(即 HTTPS)中实现了 HTTP/2,所以在实际应用中,HTTP/2 通常与 HTTPS 一起使用。

https简介

HTTPS 是 HTTP 的安全版本,它使用加密技术来保护网站和浏览器之间的数据传输。HTTPS 使用传输层安全协议(TLS)或者以前的安全套接字层协议(SSL)来加密通信协议,并使用数字签名来验证身份。HTTPS 比 HTTP 更安全,因为它可以防止或阻止一些在没有加密或认证的情况下可能发生的攻击。

HTTPS 的工作原理是使用一种称为非对称公钥基础设施的加密系统,它使用两个不同的密钥来加密两方之间的通信:

  • 私钥 - 这个密钥由网站的所有者控制,并且保持私密。这个密钥存储在网站服务器上,用于解密由公钥加密的信息。
  • 公钥 - 这个密钥可以被任何想要与服务器安全交互的人使用。由公钥加密的信息只能由私钥解密。

HTTPS 的重要性在于,它可以防止网站的信息被任何在网络上窥探的人轻易地查看。当数据通过普通的 HTTP 发送时,数据被分成可以使用免费软件轻易“嗅探”的数据包。这使得在不安全的网络上(例如公共 Wi-Fi)的通信非常容易被拦截。事实上,所有通过 HTTP 进行的通信都是以明文进行的,这使它们非常容易被任何有正确工具的人访问,并且容易受到中间人攻击。使用 HTTPS,流量被加密,以至于即使数据包被嗅探或者以其他方式被拦截,它们也只会显示为无意义的字符。

https实现过程

HTTPS使用的大致步骤如下:

  1. 首先生成一个 SSL 证书,用于加密和认证你的网站。可以使用一些工具来生成自签名的证书,例如 mkcert,或者申请一个公共的证书,例如 Let’s Encrypt。
  2. 配置 web 服务器,例如 Nginx 或 Apache,来使用你的证书,并监听 HTTPS 的端口(默认是 443)。你需要指定你的证书文件和私钥文件的路径,并设置一些 SSL 的参数,例如协议和套件。
  3. 如果使用的是自签名的证书,需要让浏览器信任你的证书,否则会出现不安全的警告。你可以将你的证书导入到浏览器的受信任的根证书颁发机构列表中;公共的证书则则可以省略这个步骤。
  4. 这样,就可以在本地或者局域网内使用 HTTPS 来访问你的网站了。你可以在浏览器的地址栏看到一个安全的标志,表示你的通信是加密的。

使用mkcert实现局域网http是的示例

mkcert 是一个用于生成本地自签名 SSL 证书的工具,适用于测试服务器和服务。它可以快速生成 SSL 证书,而无需从证书颁发机构购买。

下面是一个是在ubuntu22中简单的流程,参考的是mkcert的官方教程,首先安装mkcert并生成ssl证书,这里我的局域网ip192.168.56.101

1
2
3
4
5
6
7
8
9
10
11
12
# ubuntu22 安装mkcert
sudo apt install libnss3-tools

curl -JLO "https://dl.filippo.io/mkcert/latest?for=linux/amd64"
chmod +x mkcert-v*-linux-amd64
sudo cp mkcert-v*-linux-amd64 /usr/local/bin/mkcert

# 生成 ssl证书、私钥、公钥
mkcert 192.168.56.101

# 生成客户端证书,在客户端中受信,默认密码为:changeit
mkcert -pkcs12 -client 192.168.56.101

使用nginx建立一个简单的静态文件服务用于测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
server {
listen 443 ssl http2;
server_name 192.168.56.101;

# ssl certificate and key
ssl_certificate /usr/html/nginx/192.168.56.101.pem;
ssl_certificate_key /usr/html/nginx/192.168.56.101-key.pem;

# ssl parameters
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;

root /usr/nekoyuu/html;
location / {
add_header Access-Control-Allow-Origin *;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
}
}

http/2

当然可以,HTTP/2 是一种网络传输协议,它是 HTTP 协议的第二个主要版本。HTTP/2 的设计目标是提高网络通信的效率,解决 HTTP/1.x 版本中存在的一些性能问题。以下是 HTTP/2 的一些关键特性:

二进制分帧:HTTP/2 引入了二进制分帧层,将所有传输的信息分割为更小的消息和帧,并采用二进制格式编码。这种方式使得数据包的传输更加高效,并且可以在同一连接上交错发送多个请求和响应。
多路复用:HTTP/2 允许在单一连接上同时发送多个请求和响应,而不需要等待前一个传输完成。这减少了延迟,提高了连接的利用率,并解决了 HTTP/1.x 中的队头阻塞问题2。
头部压缩:HTTP/2 使用 HPACK 压缩算法对头部进行压缩,减少了头部大小,节约了带宽,提升了传输效率。
服务器推送:HTTP/2 允许服务器主动向客户端推送资源,而不需要客户端明确请求,这可以进一步提高页面加载速度2。
请求优先级:HTTP/2 允许客户端设置请求的优先级,让服务器根据优先级处理请求,从而优化整体性能。
HTTP/2 的这些改进使得 Web 页面的加载速度更快,响应更及时,同时也减少了服务器的负载。如果你想了解更多细节,可以查看这篇深入理解 HTTP/2 的文章或这篇HTTP/2 特性和原理的介绍。

关于http/2的其他疑问

如果你的服务器配置了 HTTP/2,浏览器不需要对现有的 JavaScript 代码进行任何修改就能够利用 HTTP/2 的优势。HTTP/2 的设计允许在单个连接上并行传输多个请求和响应,这减少了因多个 HTTP 连接而产生的开销和延迟。

HTTP/2 的多路复用功能意味着浏览器可以同时发送多个请求到服务器,而不需要等待一个请求完成后再发送下一个。这样,即使网页上有很多资源需要加载(如图片、CSS、JavaScript 文件等),浏览器也可以更高效地加载它们,因为它们可以通过同一个连接并行传输,而不是排队等待。

总的来说,HTTP/2 使得网络请求更加高效,但它是在传输层实现的,因此不需要修改应用层的代码,如 JavaScript。

这里我尝试加载了一些json文件,可以看到现在的协议已经是h2了

参考资料

  1. Copilot
  2. https://github.com/FiloSottile/mkcert
  3. https://en.wikipedia.org/wiki/HTTPS
  4. https://www.51cto.com/article/607179.html