HTTP/0.9 到 HTTP/3 进化史

一个HTTP请求流程

在地址栏输入网址后:html

  1. 构建请求:浏览器构建请求行信息如GET /index.html HTTP1.1,准备发起网络请求
  2. 查找缓存:发起网络请求前,浏览器先在缓存中查询是否有要请求的文件,若有,则拦截请求,返回资源副本,并结束请求,如无则继续
  3. 准备IP地址和端口:查找DNS缓存,如无则进行DNS查询,最终拿到请求域名对应的IP地址,HTTP协议端口默认8080
  4. 等待TCP队列:浏览器中同一个域名最多只能创建6个TCP链接,多出来的须要排队等待
  5. 创建TCP链接:浏览器经过TCP三次握手与服务器创建链接
  6. 发送HTTP请求
  7. 服务器处理HTTP请求并响应
  8. 断开TCP链接:四次挥手

HTTP/0.9

1991年提出,最初的目的只是为了传输体积很小的HTML文件,所以称为超文本传输协议。特色:浏览器

  1. 只有一个请求行如GET /index.html,没有请求头和请求体
  2. 服务器没有返回头信息,仅仅返回数据
  3. 返回文件由于都是HTML格式,因此以ASCII字符流来传输

HTTP/1.0

1994年出现了拨号上网,同年网景推出了浏览器,万维网进入了高速发展的阶段。为支持多种类型的文件下载HTTP/1.0引入了请求头和响应头。引入了状态码、提供了Cache机制来缓存下载过的资源、加入了用户代理字段。缓存

例如HTTP请求头告诉服务器本身但愿服务器返回的文件类型、压缩方法、文件的编码方式、语种:安全

accept: text/html
accept-encoding: gzip, deflate, br
accept-Charset: ISO-8859-1,utf-8
accept-language: zh-CN,zh
复制代码

服务器返回本身最终选择的方式,如压缩方法、文件类型:bash

content-encoding: br
content-type: text/html; charset=UTF-8
复制代码

HTTP/1.1

持久链接

HTTP/1.0中每一对请求响应都须要单独的TCP链接,HTTP/1.1增长了持久链接,在一个TCP链接上进行屡次请求和响应。服务器

默认是Connection: keep-alive,即开启,设置Connection: close手动关闭。cookie

配合Keep-Alive: timeout=5, max=1000来设定链接时长。其中timeout指定一个空闲链接须要保持打开状态而最小时长(单位:秒)。max指定这次链接的最大请求数。网络

目前浏览器对于同一域名容许最多同时创建6个TCP持久链接。并发

不成熟的管线化

管线化指将多个HTTP请求批量提交给服务器,服务器依然根据请求顺序来回复浏览器的请求。因为种种缘由,这个技术的尝试失败了。post

支持虚拟主机

HTTP/1.0中一个IP地址只能绑定一个域名,所以服务器只能支持一个域名。随着虚拟主机技术的发展,须要实现一台物理主机上绑定多个各自拥有域名的虚拟主机。HTTP/1.1在请求头中增长了Host字段,用来表示当前域名,供服务器区分。

支持动态生成的内容

HTTP/1.0中须要在响应头中设置完整的数据大小如Content-Length: 901,以便浏览器根据数据大小准确接收数据。但对于动态生成的内容,传输前不知道最终大小,致使浏览器没法正确接收全部数据。

HTTP/1.1引入了Chunk transfer机制,服务器将数据分割成若干大小的数据块,每一个数据块发送时都会附上数据块的长度,最后使用一个零长度的块来结束。这样就能够支持动态内容了。

客户端Cookie、安全机制
客户端Cookie机制

用户登陆时,服务器验证用户登陆信息正确后,会生成一段表示用户身份的字符串,并写入响应头Set-Cookie字段里,而后发送给浏览器,如Set-Cookie: UID=3431uad;

浏览器将Set-Cookie字段中的值保存到本地,当用户再次访问服务器时,浏览器会读取以前保存的Cookie数据并写入请求头的Cookie字段中,如Cookie: UID=3431uad;

服务器根据Cookie字段中的值查找该用户的信息,判断是否已登陆,而后生成包含该用户信息的页面数据,返回给浏览器。

安全机制

HttpOnly:Set-Cookie: id=a3fWa; HttpOnly。禁止JavaScript经过document.cookie访问cookie,以阻止XSS攻击。

SameSite: Set-Cookie: id=a3fWa; SameSite=Strict。SameSite有三个值:

  • Node: 浏览器会在同站请求、跨站请求下继续发送cookies,不区分大小写。
  • Strict:浏览器只在访问相同站点时发送cookie。
  • Lax:新版浏览器的默认选项,在跨站点的状况下,只容许从第三方站点经过连接打开或get请求携带Cookie,经过post或img、iframe等标签加载的url不会携带cookie。
问题

TCP通道中,须要等待前面的请求返回后才能进行下一次请求,若是某个请求由于某些缘由没有及时返回,就会阻塞后面的全部请求,这就是队头阻塞的问题。

HTTP/2

多路复用

2015年5月正式发布HTTP/2协议规范,该协议使用多路复用机制,实现一个域名只使用一个TCP长链接,并消除了队头阻塞问题。多路复用技术能充分利用带宽,最大限度规避了TCP慢启动所带来的问题,使得页面资源的传输速度获得了大幅提高。 使用HTTP/2能带来20% ~ 60%的效率提高。

HTTP/2添加了一个二进制分帧层,将通过的请求转换为一个个带有请求ID编号的帧,服务器接收到全部帧以后,将全部相同ID的帧合并为一条完整的请求信息,处理完请求后,将响应也一样用二进制分帧层转换为一个个带有请求ID编号的帧,浏览器接收到响应帧后根据ID编号将数据提交给对应的请求。

浏览器能够随时发送请求,而没必要等待前一个请求接收到响应以后;一样,服务器也能够按需决定优先返回哪些内容,而没必要在乎顺序,由于每份数据都有ID来标识。这样就实现了资源的并行传输。

HTTP/2的其余特性:
  1. 能够设置请求的优先级:服务器不须要按顺序处理请求,所以对于一些优先级比较高的请求,如关键资源的加载,能够在发送请求时标注优先级,服务器接收到请求后,会优先处理优先级高的请求。
  2. 服务器推送:服务器能够将数据提早推送到浏览器,例如:用户请求首页HTML文件后,服务器知道该页面会引用几个重要的JavaScript文件和CSS文件,因而能够附带将这些文件一并发送给浏览器,加快渲染速度。
  3. 头部压缩:HTTP/2对请求头和响应头进行了压缩,在一些大量发送请求体比较少的请求的状况下,传输效率会获得很大的提高。

HTTP/3

HTTP/2解决了应用层面的队头阻塞问题,但只要仍是基于TCP,就避免不了TCP的队头阻塞问题。而TCP在设计之初就是为了单连接而设计。

TCP的问题
  1. 队头阻塞:TCP传输的数据被拆分红一个个按顺序排列的数据包,接收端收到后再按顺序将这些数据包组成原始数据。若是在传输过程当中,有一个数据包由于网络故障或其它缘由丢失,以后的数据就得等待丢失的数据包被从新传输过来,形成了阻塞。而HTTP/2只有一个链接,其余全部请求都会被阻塞。随着丢包率的增长,HTTP/2的传输效率也愈来愈差。
  2. 创建链接的延时:TCP创建链接时的三次握手,若是是HTTPS还有TLS链接握手,总体就须要3~4个RTT(TCP1.5个,TLS根据1.2/1.3版本会有不一样的表现)。
  3. 协议僵化:互联网须要不少中间设备来说多个网络互联,这些中间设备包括路由器、防火墙、NAT、交换机等。它们一般依赖一些不多升级的软件,这些软件使用了大量TCP特性,即使客户端升级了TCP协议,新协议的数据通过这些中间设备时,也可能会由于不被理解而丢弃。此外,TCP协议都是经过操做系统内核来实现的,一般操做系统的更新都滞后于软件的更新,也是致使TCP协议僵化的一个缘由。
QUIC协议

HTTP/3基于UDP协议实现了相似于TCP的多路复用数据流、传输可靠性等功能,这套功能被称为QUIC协议。

  1. 流量控制、传输可靠性功能:QUIC在UDP的基础上增长了一层来保证数据传输可靠性,它提供了数据包重传、拥塞控制、以及其余一些TCP中的特性。
  2. 集成TLS加密功能:目前QUIC使用TLS1.3,减小了握手所花费的RTT数。
  3. 多路复用:同一物理链接上能够有多个独立的逻辑数据流,实现了数据流的单独传输,解决了TCP的队头阻塞问题。

  1. 快速握手:因为基于UDP,能够实现使用0 ~ 1个RTT来创建链接。
HTTP/3的挑战
  1. 目前服务器和浏览器端都没有对HTTP/3提供比较完整的支持。
  2. 部署问题,系统内核对UDP的优化远达不到TCP的优化程度。
  3. 中间设备僵化问题,这些设备对UDP的优化程度远低于TCP,据统计使用QUIC协议时,大约有3% ~ 7%的丢包率。
相关文章
相关标签/搜索