前言
http从0.9版本发展到如今的3.0版本,到底都经历了些什么,我将用简练的语言在本篇文章中详细介绍http的发家史
HTTP是什么:
HTTP 即超文本传输协议(HyperText Transfer Protocol),是一种用于在网络上传输超文本数据的,建立在 TCP/IP 协议之上的 应用层协议,它规定了客户端和服务器之间进行数据交换的格式和规则。
不了解TCP的同学可以看这里:计算机网络:UDP协议和TCP协议详解
HTTP/0.9
-
诞生背景:1990 年问世,当时互联网处于发展初期,主要需求是在网络上传输超文本信息。
-
特点
-
只有请求行,没有请求头,没有请求体
GET /chat/index.html 请求行 (只能发GET请求)
-
服务端没有返回头信息
-
返回的内容是以ASCII的字符流传输的
-
-
HTTP/0.9的完整的请求流程
- 建立 TCP 连接:客户端根据服务器的 IP 地址和端口号,通过 TCP 协议的三次握手与服务器建立连接。
- 发送请求:连接建立后,客户端向服务器发送一个简单的 GET 请求行,例如
GET /index.html,以请求获取指定的 HTML 文件。此时的请求只有请求行,没有请求头和请求体,因为在 HTTP/0.9 中,一个请求行就足以表达客户端获取 HTML 文件的需求。 - 服务器处理请求并响应:服务器接收到请求后,读取对应的 HTML 文件,并将文件内容以 ASCII 字符流的形式返回给客户端。服务器的响应没有响应头信息,只返回数据,因为当时的设计理念是服务器不需要向客户端传达太多额外信息。
- 关闭连接:HTML 文档传输完成后,服务器会断开与客户端的 TCP 连接,一次完整的 HTTP/0.9 请求流程结束。
HTTP/1.0
-
诞生背景:随着网络应用的逐渐丰富,需要更完善的协议来支持多样化的功能和数据传输,万维网联盟 (w3c)和 HTTP 工作组成立,1996 年发布了 HTTP/1.0。
-
1.0需要解决的问题: 因为此时浏览器想要展示的不仅是 html,还有图片,音频,视频等,需要支持不仅限于ASCII的编码,还需要支持多种编码处理其他文件。
- 浏览器需要知道服务器返回的内容是什么类型
- 服务器需要知道 服务器用了什么压缩方式
- 浏览器要能告诉服务器自己需要的语言类型
- 浏览器需要知道文件编码类型
-
特点:
- 增加了请求头:
- accept: text/html
- accept-encoding:gzip,deflate,br (浏览器能接受的压缩方式)
- accept-language:zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 (浏览器能读懂的语言)
- accept-charset: UTF-8.ISO-8859-1;q=0.7(浏览器能接受的编码类型)
- 增加了响应头:
- content-type:text/xml (服务器返回的类型)
- content-encoding:(服务器用的压缩方式)
- content-language:(服务器用的语言类型)
-
状态码:
- 2xx 成功
- 200 成功
- 204 成功 但是没有实体
- 205 成功 但是报文没有内容
- 206 成功 成功,报文只含有实体的一部分
- 3xx 重定向
- 301 永久重定向
- 302 临时重定向
- 303 临时重定向,使用GET请求
- 304 协商缓存
- 4xx
- 400 请求错误(报文存在语法错误)
- 401 未授权
- 403 禁止访问(权限不足)
- 404 未找到
- 5xx
- 500 服务器内部错误
- 501 服务器不支持当前请求所需功能
- 502 作为网关或代理工具的服务器尝试执行请求时,从远程服务器接收到了一个无效响应
- 503 服务器暂时处于超负载或者正在进行停机维护,无法处理请求
- 2xx 成功
-
其他新增特性
- 增加了请求头:
-
为了减轻服务器的压力,在 HTTP/1.0 中提供了
Cache机制,用来缓存已经下载过的数据。 -
服务器需要统计客户端的基础信息,比如 Windows 和 macOS 的用户数量分别是多少,所以 HTTP/1.0 的请求头中还加入了
用户代理的字段。
HTTP/1.1
-
诞生背景:由于1.0每一次请求都需要重新建立连接,这大大的浪费资源,且技术发展很快,不断更新迭代,所以HTTP1.1应运而生
-
特点
1. 增加了持久连接(一个TCP连接中传输多个http请求)
随着浏览器普及,有时候一个页面可能包含了几百个外部引用的资源文件,如果在下载每个文件的时候,都需要经历
HTTP/1.0中建立 TCP 连接、传输数据和断开连接这样的步骤,这造成大量资源浪费。 为了解决这个问题,HTTP/1.1中增加了持久连接的方法,它的特点是在一个 TCP 连接上可以传输多个 HTTP 请求(默认为6个),只要浏览器或者服务器没有明确断开连接,那么该 TCP 连接会一直保持。通过在请求头和响应头中设置Connection: keep - alive字段来实现。大提高了带宽的利用率。2. HTTP 管线化
持久连接虽然能减少 TCP 的建立和断开次数,但是它需要等待前面的请求返回之后,才能进行下一次请求。如果 TCP 通道中的某个请求因为一些原因没有及时返回,那么就会阻塞后面的所有请求,这就是著名的队头阻塞的问题。
HTTP/1.1中试图通过管线化的技术来解决队头阻塞的问题。HTTP/1.1 中的管线化是指将多个 HTTP 请求整批提交给服务器的技术,虽然可以整批发送请求,不过服务器依然需要根据请求顺序来回复浏览器的请求。3. 增加了 host 字段
在 HTTP/1.1 中,
Host字段是一个必须的请求头字段。它用于指定请求的目标服务器的域名或 IP 地址以及端口号(如果不是默认端口)。这是因为在 HTTP/1.1 时代,一台服务器可能会承载多个不同域名的网站,通过Host字段,服务器可以准确地知道客户端请求的是哪个网站的资源,从而正确地处理请求并返回相应的内容。4. 客户端增加了cookie
Cookie 是服务器发送到客户端并存储在客户端的一小段数据。在 HTTP/1.1 中,客户端可以在后续的请求中通过
Cookie请求头字段将这些数据发送回服务器。Cookie 主要用于识别用户身份、记录用户的登录状态、购物车信息等。服务器可以根据客户端发送的 Cookie 来为用户提供个性化的服务,例如在用户再次访问网站时自动登录,或者根据用户的浏览历史推荐相关内容。
HTTP/2
- 诞生背景:随着 Web 应用的日益复杂和对性能要求的不断提高,HTTP/1.1 的性能瓶颈逐渐显现,为了进一步提升 Web 性能,2015 年发布了 HTTP/21。
- 队头阻塞问题
如果 TCP 通道中的某个请求因为某些原因没有及时返回,那么就会阻塞后面的所有请求。管线化并不能完全解决这个问题,所以在http2.0中提出了多路复用
-
多路复用
概念
HTTP/2 的多路复用允许在同一个连接上同时发送多个请求和响应,而不会像 HTTP/1.x 那样存在队头阻塞的问题。多个请求和响应可以交织在一起,通过帧的形式在连接上进行传输,然后在客户端和服务器端进行正确的组装和解析。
工作原理
- 二进制分帧:HTTP/2 将所有的通信都分解为更小的、固定长度的帧,这些帧可以包含不同类型的信息,如请求头、请求体、响应头、响应体等。每个帧都有一个唯一的标识符,用于在连接上区分不同的流。
- 流的管理:流是一个独立的、双向的字节序列,它可以承载一个完整的请求 - 响应交互。多个流可以在同一个连接上同时进行,每个流都有自己的优先级和状态。客户端和服务器可以根据需要创建、暂停、恢复或关闭流。
- 帧的交织与组装:不同流的帧可以在连接上交织传输,这样可以充分利用连接的带宽,提高传输效率。在接收端,根据帧的标识符和相关的控制信息,将帧正确地组装成完整的请求和响应。
-
让我们打一个比方,帮助我们来理解: 可以将 HTTP/2 的多路复用比作一条多车道的高速公路,来帮助你理解:
- HTTP/1.x 单车道模式:假设 HTTP/1.x 就像一条只有单车道的公路,每次只能有一辆车在这条路上行驶。如果有很多辆车要从 A 地到 B 地,它们就必须一辆接一辆地排队行驶。一旦前面有辆车出现故障或者开得很慢,后面的车都得跟着停下来等待,这就导致整个交通效率很低,就像 HTTP/1.x 中存在队头阻塞问题,一个请求的延迟会影响后续所有请求。
- HTTP/2 多车道模式:HTTP/2 的多路复用就像是把这条公路扩建成了有多个车道的高速公路。多辆车可以同时在不同的车道上行驶,即使某条车道上的车因为某些原因减速或停止,也不会影响其他车道上的车正常行驶。这些不同车道就相当于 HTTP/2 中的不同流,每辆车就好比是一个请求或响应,它们可以在各自的车道上独立地前进,多个请求和响应能够在同一个连接(高速公路)上同时传输,大大提高了传输效率,避免了因为单个请求的问题而阻塞整个连接的情况。
- 多路复用还有一个好处是:二进制分帧层,将请求全部打包成帧,帧与帧之间互不干扰,打上编号,服务端可以根据编号的优先级来处理加急的请求。
小tip:2015 年正式发布的 HTTP/2 默认不再使用 ASCII 编码传输,而是改为二进制数据,来提升传输效率
HTTP/3
诞生背景:尽管 HTTP/2 在性能上有了很大的提升,但在一些高延迟、高丢包率的网络环境下,如移动网络,基于 TCP 协议的 HTTP/2 仍然存在一些局限性。为了进一步提升性能和安全性,2020 年发布了 HTTP/3
因为tcp协议的僵化:
- tcp的队头阻塞 (超时重传)
- tcp的慢启动
- tcp的三次握手和四次挥手的耗时
特点
- 基于 QUIC 协议:HTTP/3的主要思想就是抛弃TCP协议,打造基于 UDP 协议的
QUIC协议,取代 TCP 作为传输层协议。
QUIC协议
- 低延迟:QUIC 协议在建立连接时,通过使用 0 - RTT(Round - Trip Time)或 1 - RTT 即可完成握手和数据传输,相比 TCP 协议通常需要 3 - RTT 才能开始传输数据,大大减少了连接建立的延迟。
- 多路复用:类似于 HTTP/2 的多路复用,QUIC 允许在同一个连接上同时发送多个数据流,不同的数据流之间相互独立,不会出现队头阻塞问题,提高了连接的利用率和数据传输效率。
- 连接迁移:当设备的网络环境发生变化,如从 Wi - Fi 切换到移动数据网络时,QUIC 能够在不中断连接的情况下,快速将连接迁移到新的网络接口上,保证数据传输的连续性,这对于移动设备等经常发生网络切换的场景非常重要。
- 安全性:QUIC 协议默认使用加密传输,采用了 TLS 1.3 协议进行加密,为数据提供了端到端的安全保护,防止数据被窃取或篡改。
- 流量控制:QUIC 协议实现了基于信用的流量控制机制,发送方根据接收方反馈的信用值来控制发送数据的速率,避免发送数据过快导致接收方缓冲区溢出,同时也能根据网络状况动态调整发送速率,提高网络资源的利用率。
现实
当然, 设备更换成本导致3.0没有普及开来,也许我们在不久的将来,它就会完全融入我们的生活中啦。
多提一嘴:http 和 httpss的区别
- HTTPS 是 HTTP 的安全版本 (HTTP+SSL/TLS)
我觉得TLS加密方式这个很有趣,所以在这里和读者们聊聊:
TLS
对称加密算法:TLS 使用对称加密算法对数据进行加密和解密,对称加密算法的特点是加密和解密使用相同的密钥,加密速度快,适合对大量数据进行加密。 例如,在 TLS 握手过程完成后,客户端和服务器会协商一个对称加密密钥,然后使用该密钥对后续传输的数据进行加密,确保数据在传输过程中的保密性。
非对称加密算法:非对称加密算法用于 TLS 中的密钥交换和身份认证,非对称加密算法有一对密钥,即公钥和私钥,公钥可以公开,私钥由所有者保密。
- 客户端生成密钥
- 服务端生成公钥+私钥
- 客户端利用公钥加密密钥并传输给服务端
- 服务端利用私钥解密密钥
- 客户端和服务端都拥有相同的密钥,两边都知道如何解密
- 客户端和服务端之间的通信都是加密的
用一个小例子来说明:
我们让客户端为A,服务端为B。B生成一个箱子和钥匙(公钥+私钥),A生成个密码本(密钥),B把箱子给A,但是钥匙留在自己手上, A把密码本(密钥)装进箱子(公钥),箱子里边装着密码本(公钥+密钥)还给B,B此时就能把箱子打开得到密码本(密钥)。这样两人都得到密码本了,就可以解密啦。
结语
HTTP的发展史大概就是这样啦,如果出现什么错误的地方,还请大家多多指教。也许在不远的将来,抑或是很近很近的将来,HTTP又碰到一些新的问题,出现新的版本,谁知道呢,这就是技术的魅力,不断发现错误,不断进步,不断改正,不断发展。